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 2014/12/11 10:15:20 UTC

[4/4] camel git commit: CAMEL-8044: Camel commands should be more reusable for remote JVMs

CAMEL-8044: Camel commands should be more reusable for remote JVMs


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a9eb7169
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a9eb7169
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a9eb7169

Branch: refs/heads/master
Commit: a9eb716950804b3bb01d52d2ea42e38104761490
Parents: 5e774fa
Author: Claus Ibsen <da...@apache.org>
Authored: Thu Dec 11 10:09:38 2014 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Thu Dec 11 10:15:05 2014 +0100

----------------------------------------------------------------------
 .../mbean/ManagedCamelContextMBean.java         |   2 +-
 .../management/mbean/ManagedCamelContext.java   |   2 +
 .../apache/camel/util/CamelContextStatDump.java | 302 +++++++++++++++++++
 .../apache/camel/util/ProcessorStatDump.java    |   2 +-
 .../org/apache/camel/util/RouteStatDump.java    |   2 +-
 .../camel/commands/AbstractCamelController.java |  22 ++
 .../apache/camel/commands/CamelController.java  |  11 +
 .../camel/commands/ContextInfoCommand.java      | 151 ++++------
 .../camel/commands/RestRegistryListCommand.java |   8 +-
 .../apache/camel/commands/RouteInfoCommand.java |  14 +-
 .../camel/karaf/commands/ContextInfo.java       |   8 +-
 11 files changed, 422 insertions(+), 102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
index 7105fb5..fc892b6 100644
--- a/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
+++ b/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
@@ -181,7 +181,7 @@ public interface ManagedCamelContextMBean extends ManagedPerformanceCounterMBean
     @ManagedOperation(description = "Adds or updates existing routes from XML")
     void addOrUpdateRoutesFromXml(String xml, boolean urlDecode) throws Exception;
 
-    @ManagedOperation(description = "Dumps the routes stats as XML")
+    @ManagedOperation(description = "Dumps the CamelContext and routes stats as XML")
     String dumpRoutesStatsAsXml(boolean fullStats, boolean includeProcessors) throws Exception;
 
     /**

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index f3d2be5..d955cc6 100644
--- a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -373,6 +373,7 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
         sb.append("<camelContextStat").append(String.format(" id=\"%s\" state=\"%s\"", getCamelId(), getState()));
         // use substring as we only want the attributes
         String stat = dumpStatsAsXml(fullStats);
+        sb.append(" exchangesInflight=\"").append(getInflightExchanges()).append("\"");
         sb.append(" ").append(stat.substring(7, stat.length() - 2)).append(">\n");
 
         MBeanServer server = getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
@@ -400,6 +401,7 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
                 sb.append("    <routeStat").append(String.format(" id=\"%s\" state=\"%s\"", route.getRouteId(), route.getState()));
                 // use substring as we only want the attributes
                 stat = route.dumpStatsAsXml(fullStats);
+                sb.append(" exchangesInflight=\"").append(context.getInflightRepository().size(route.getRouteId())).append("\"");
                 sb.append(" ").append(stat.substring(7, stat.length() - 2)).append(">\n");
 
                 // add processor details if needed

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/camel-core/src/main/java/org/apache/camel/util/CamelContextStatDump.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/CamelContextStatDump.java b/camel-core/src/main/java/org/apache/camel/util/CamelContextStatDump.java
new file mode 100644
index 0000000..08680c3
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/util/CamelContextStatDump.java
@@ -0,0 +1,302 @@
+/**
+ * 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.util;
+
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * A model of a CamelContext stat dump from {@link org.apache.camel.api.management.mbean.ManagedCamelContextMBean#dumpRoutesStatsAsXml(boolean, boolean)}.
+ */
+@XmlRootElement(name = "camelContextStat")
+@XmlAccessorType(XmlAccessType.FIELD)
+public final class CamelContextStatDump {
+
+    @XmlAttribute
+    private String id;
+
+    @XmlAttribute
+    private String state;
+
+    @XmlAttribute
+    private Long exchangesCompleted;
+
+    @XmlAttribute
+    private Long exchangesFailed;
+
+    @XmlAttribute
+    private Long failuresHandled;
+
+    @XmlAttribute
+    private Long redeliveries;
+
+    @XmlAttribute
+    private Long minProcessingTime;
+
+    @XmlAttribute
+    private Long maxProcessingTime;
+
+    @XmlAttribute
+    private Long totalProcessingTime;
+
+    @XmlAttribute
+    private Long lastProcessingTime;
+
+    @XmlAttribute
+    private Long deltaProcessingTime;
+
+    @XmlAttribute
+    private Long meanProcessingTime;
+
+    @XmlAttribute
+    private Long exchangesInflight;
+
+    @XmlAttribute
+    private Long selfProcessingTime;
+
+    @XmlAttribute
+    private String resetTimestamp;
+
+    @XmlAttribute
+    private String firstExchangeCompletedTimestamp;
+
+    @XmlAttribute
+    private String firstExchangeCompletedExchangeId;
+
+    @XmlAttribute
+    private String firstExchangeFailureTimestamp;
+
+    @XmlAttribute
+    private String firstExchangeFailureExchangeId;
+
+    @XmlAttribute
+    private String lastExchangeCompletedTimestamp;
+
+    @XmlAttribute
+    private String lastExchangeCompletedExchangeId;
+
+    @XmlAttribute
+    private String lastExchangeFailureTimestamp;
+
+    @XmlAttribute
+    private String lastExchangeFailureExchangeId;
+
+    @XmlElementWrapper(name = "routeStats")
+    @XmlElements({
+            @XmlElement(type = RouteStatDump.class, name = "routeStat")
+    })
+    private List<RouteStatDump> routeStats;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public Long getExchangesCompleted() {
+        return exchangesCompleted;
+    }
+
+    public void setExchangesCompleted(Long exchangesCompleted) {
+        this.exchangesCompleted = exchangesCompleted;
+    }
+
+    public Long getExchangesFailed() {
+        return exchangesFailed;
+    }
+
+    public void setExchangesFailed(Long exchangesFailed) {
+        this.exchangesFailed = exchangesFailed;
+    }
+
+    public Long getFailuresHandled() {
+        return failuresHandled;
+    }
+
+    public void setFailuresHandled(Long failuresHandled) {
+        this.failuresHandled = failuresHandled;
+    }
+
+    public Long getRedeliveries() {
+        return redeliveries;
+    }
+
+    public void setRedeliveries(Long redeliveries) {
+        this.redeliveries = redeliveries;
+    }
+
+    public Long getMinProcessingTime() {
+        return minProcessingTime;
+    }
+
+    public void setMinProcessingTime(Long minProcessingTime) {
+        this.minProcessingTime = minProcessingTime;
+    }
+
+    public Long getMaxProcessingTime() {
+        return maxProcessingTime;
+    }
+
+    public void setMaxProcessingTime(Long maxProcessingTime) {
+        this.maxProcessingTime = maxProcessingTime;
+    }
+
+    public Long getTotalProcessingTime() {
+        return totalProcessingTime;
+    }
+
+    public void setTotalProcessingTime(Long totalProcessingTime) {
+        this.totalProcessingTime = totalProcessingTime;
+    }
+
+    public Long getLastProcessingTime() {
+        return lastProcessingTime;
+    }
+
+    public void setLastProcessingTime(Long lastProcessingTime) {
+        this.lastProcessingTime = lastProcessingTime;
+    }
+
+    public Long getDeltaProcessingTime() {
+        return deltaProcessingTime;
+    }
+
+    public void setDeltaProcessingTime(Long deltaProcessingTime) {
+        this.deltaProcessingTime = deltaProcessingTime;
+    }
+
+    public Long getMeanProcessingTime() {
+        return meanProcessingTime;
+    }
+
+    public void setMeanProcessingTime(Long meanProcessingTime) {
+        this.meanProcessingTime = meanProcessingTime;
+    }
+
+    public Long getSelfProcessingTime() {
+        return selfProcessingTime;
+    }
+
+    public void setSelfProcessingTime(Long selfProcessingTime) {
+        this.selfProcessingTime = selfProcessingTime;
+    }
+
+    public Long getExchangesInflight() {
+        return exchangesInflight;
+    }
+
+    public void setExchangesInflight(Long exchangesInflight) {
+        this.exchangesInflight = exchangesInflight;
+    }
+
+    public String getResetTimestamp() {
+        return resetTimestamp;
+    }
+
+    public void setResetTimestamp(String resetTimestamp) {
+        this.resetTimestamp = resetTimestamp;
+    }
+
+    public String getFirstExchangeCompletedTimestamp() {
+        return firstExchangeCompletedTimestamp;
+    }
+
+    public void setFirstExchangeCompletedTimestamp(String firstExchangeCompletedTimestamp) {
+        this.firstExchangeCompletedTimestamp = firstExchangeCompletedTimestamp;
+    }
+
+    public String getFirstExchangeCompletedExchangeId() {
+        return firstExchangeCompletedExchangeId;
+    }
+
+    public void setFirstExchangeCompletedExchangeId(String firstExchangeCompletedExchangeId) {
+        this.firstExchangeCompletedExchangeId = firstExchangeCompletedExchangeId;
+    }
+
+    public String getFirstExchangeFailureTimestamp() {
+        return firstExchangeFailureTimestamp;
+    }
+
+    public void setFirstExchangeFailureTimestamp(String firstExchangeFailureTimestamp) {
+        this.firstExchangeFailureTimestamp = firstExchangeFailureTimestamp;
+    }
+
+    public String getFirstExchangeFailureExchangeId() {
+        return firstExchangeFailureExchangeId;
+    }
+
+    public void setFirstExchangeFailureExchangeId(String firstExchangeFailureExchangeId) {
+        this.firstExchangeFailureExchangeId = firstExchangeFailureExchangeId;
+    }
+
+    public String getLastExchangeCompletedTimestamp() {
+        return lastExchangeCompletedTimestamp;
+    }
+
+    public void setLastExchangeCompletedTimestamp(String lastExchangeCompletedTimestamp) {
+        this.lastExchangeCompletedTimestamp = lastExchangeCompletedTimestamp;
+    }
+
+    public String getLastExchangeCompletedExchangeId() {
+        return lastExchangeCompletedExchangeId;
+    }
+
+    public void setLastExchangeCompletedExchangeId(String lastExchangeCompletedExchangeId) {
+        this.lastExchangeCompletedExchangeId = lastExchangeCompletedExchangeId;
+    }
+
+    public String getLastExchangeFailureTimestamp() {
+        return lastExchangeFailureTimestamp;
+    }
+
+    public void setLastExchangeFailureTimestamp(String lastExchangeFailureTimestamp) {
+        this.lastExchangeFailureTimestamp = lastExchangeFailureTimestamp;
+    }
+
+    public String getLastExchangeFailureExchangeId() {
+        return lastExchangeFailureExchangeId;
+    }
+
+    public void setLastExchangeFailureExchangeId(String lastExchangeFailureExchangeId) {
+        this.lastExchangeFailureExchangeId = lastExchangeFailureExchangeId;
+    }
+
+    public List<RouteStatDump> getRouteStats() {
+        return routeStats;
+    }
+
+    public void setRouteStats(List<RouteStatDump> routeStats) {
+        this.routeStats = routeStats;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/camel-core/src/main/java/org/apache/camel/util/ProcessorStatDump.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/ProcessorStatDump.java b/camel-core/src/main/java/org/apache/camel/util/ProcessorStatDump.java
index 000613e..396f4f0 100644
--- a/camel-core/src/main/java/org/apache/camel/util/ProcessorStatDump.java
+++ b/camel-core/src/main/java/org/apache/camel/util/ProcessorStatDump.java
@@ -22,7 +22,7 @@ import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 
 /**
- * A model of a route stat dump from {@link org.apache.camel.api.management.mbean.ManagedRouteMBean#dumpRouteAsXml()}.
+ * A model of a route stat dump from {@link org.apache.camel.api.management.mbean.ManagedRouteMBean#dumpRouteStatsAsXml(boolean, boolean)}.
  */
 @XmlRootElement(name = "processorStat")
 @XmlAccessorType(XmlAccessType.FIELD)

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/camel-core/src/main/java/org/apache/camel/util/RouteStatDump.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/RouteStatDump.java b/camel-core/src/main/java/org/apache/camel/util/RouteStatDump.java
index 4a05413..9079384 100644
--- a/camel-core/src/main/java/org/apache/camel/util/RouteStatDump.java
+++ b/camel-core/src/main/java/org/apache/camel/util/RouteStatDump.java
@@ -26,7 +26,7 @@ import javax.xml.bind.annotation.XmlElements;
 import javax.xml.bind.annotation.XmlRootElement;
 
 /**
- * A model of a route stat dump from {@link org.apache.camel.api.management.mbean.ManagedRouteMBean#dumpRouteAsXml()}.
+ * A model of a route stat dump from {@link org.apache.camel.api.management.mbean.ManagedRouteMBean#dumpRouteStatsAsXml(boolean, boolean)}.
  */
 @XmlRootElement(name = "routeStat")
 @XmlAccessorType(XmlAccessType.FIELD)

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
index 51c2f7c..df0fb78 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/AbstractCamelController.java
@@ -91,6 +91,28 @@ public abstract class AbstractCamelController implements CamelController {
         return answer;
     }
 
+    public String getCamelContextStatsAsXml(String camelContextName, boolean fullStats, boolean includeProcessors) throws Exception {
+        CamelContext context = this.getCamelContext(camelContextName);
+        if (context == null) {
+            return null;
+        }
+
+        ManagementAgent agent = context.getManagementStrategy().getManagementAgent();
+        if (agent != null) {
+            MBeanServer mBeanServer = agent.getMBeanServer();
+            ObjectName query = ObjectName.getInstance(agent.getMBeanObjectDomainName() + ":type=context,*");
+            Set<ObjectName> set = mBeanServer.queryNames(query, null);
+            for (ObjectName contextMBean : set) {
+                String camelId = (String) mBeanServer.getAttribute(contextMBean, "CamelId");
+                if (camelId != null && camelId.equals(context.getName())) {
+                    String xml = (String) mBeanServer.invoke(contextMBean, "dumpRoutesStatsAsXml", new Object[]{fullStats, includeProcessors}, new String[]{"boolean", "boolean"});
+                    return xml;
+                }
+            }
+        }
+        return null;
+    }
+
     public void startContext(String camelContextName) throws Exception {
         CamelContext context = getCamelContext(camelContextName);
         if (context != null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
index 6f781a0..dc696a5 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/CamelController.java
@@ -70,6 +70,17 @@ public interface CamelController {
     List<Map<String, String>> getCamelContexts2() throws Exception;
 
     /**
+     * Returns detailed CamelContext and route statistics as XML identified by a ID and a Camel context.
+     *
+     * @param camelContextName  the Camel context.
+     * @param fullStats         whether to include verbose stats
+     * @param includeProcessors whether to embed per processor stats from the route
+     * @return the CamelContext statistics as XML
+     * @throws java.lang.Exception can be thrown
+     */
+    String getCamelContextStatsAsXml(String camelContextName, boolean fullStats, boolean includeProcessors) throws Exception;
+
+    /**
      * Starts the given Camel context.
      *
      * @param camelContextName the Camel context.

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
index e85bceb..caa085d 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/ContextInfoCommand.java
@@ -17,38 +17,36 @@
 package org.apache.camel.commands;
 
 import java.io.PrintStream;
+import java.io.StringReader;
 import java.text.SimpleDateFormat;
 import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
 
-import org.apache.camel.CamelContext;
-import org.apache.camel.Route;
-import org.apache.camel.spi.ManagementAgent;
+import org.apache.camel.util.CamelContextStatDump;
 
-import static org.apache.camel.util.UnitUtils.printUnitFromBytes;
+import static org.apache.camel.util.ObjectHelper.isEmpty;
 
 /**
  * Command to display detailed information about a given {@link org.apache.camel.CamelContext}.
  */
 public class ContextInfoCommand extends AbstractCamelCommand {
 
+    public static final String XML_TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
+    public static final String OUTPUT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
     private StringEscape stringEscape;
     private String context;
-    private String mode;
+    private boolean verbose;
 
 
     /**
      * @param context The name of the Camel context
-     * @param mode Allows for different display modes (--verbose, etc)
+     * @param verbose Whether to output verbose
      */
-    public ContextInfoCommand(String context, String mode) {
+    public ContextInfoCommand(String context, boolean verbose) {
         this.context = context;
-        this.mode = mode;
+        this.verbose = verbose;
     }
 
     /**
@@ -98,84 +96,68 @@ public class ContextInfoCommand extends AbstractCamelCommand {
         out.println(stringEscape.unescapeJava("\tPackageScanClassResolver: " + row.get("packageScanClassResolver")));
         out.println(stringEscape.unescapeJava("\tApplicationContextClassLoader: " + row.get("applicationContextClassLoader")));
 
-        // the statistics are in the mbeans
-        // TODO: use dump stats as xml
-        // printCamelManagedBeansStatus(camelContext, out);
+        if (verbose) {
+            printStatistics(camelController, out);
+        }
 
         return null;
     }
 
-    protected void printCamelManagedBeansStatus(CamelContext camelContext, PrintStream out) throws Exception {
-        // the statistics are in the mbeans
+    protected void printStatistics(CamelController camelController, PrintStream out) throws Exception {
         out.println("");
         out.println(stringEscape.unescapeJava("\u001B[1mStatistics\u001B[0m"));
-        ObjectName contextMBean = null;
-        ManagementAgent agent = camelContext.getManagementStrategy().getManagementAgent();
-        if (agent != null) {
-            MBeanServer mBeanServer = agent.getMBeanServer();
-
-            Set<ObjectName> set = mBeanServer.queryNames(new ObjectName(agent.getMBeanObjectDomainName() + ":type=context,name=\"" + context + "\",*"), null);
-            Iterator<ObjectName> iterator = set.iterator();
-            if (iterator.hasNext()) {
-                contextMBean = iterator.next();
-            }
 
-            if (mBeanServer.isRegistered(contextMBean)) {
-                Long exchangesTotal = (Long) mBeanServer.getAttribute(contextMBean, "ExchangesTotal");
-                out.println(stringEscape.unescapeJava("\tExchanges Total: " + exchangesTotal));
-                Long exchangesCompleted = (Long) mBeanServer.getAttribute(contextMBean, "ExchangesCompleted");
-                out.println(stringEscape.unescapeJava("\tExchanges Completed: " + exchangesCompleted));
-                Long exchangesFailed = (Long) mBeanServer.getAttribute(contextMBean, "ExchangesFailed");
-                out.println(stringEscape.unescapeJava("\tExchanges Failed: " + exchangesFailed));
-                Long minProcessingTime = (Long) mBeanServer.getAttribute(contextMBean, "MinProcessingTime");
-                out.println(stringEscape.unescapeJava("\tMin Processing Time: " + minProcessingTime + "ms"));
-                Long maxProcessingTime = (Long) mBeanServer.getAttribute(contextMBean, "MaxProcessingTime");
-                out.println(stringEscape.unescapeJava("\tMax Processing Time: " + maxProcessingTime + "ms"));
-                Long meanProcessingTime = (Long) mBeanServer.getAttribute(contextMBean, "MeanProcessingTime");
-                out.println(stringEscape.unescapeJava("\tMean Processing Time: " + meanProcessingTime + "ms"));
-                Long totalProcessingTime = (Long) mBeanServer.getAttribute(contextMBean, "TotalProcessingTime");
-                out.println(stringEscape.unescapeJava("\tTotal Processing Time: " + totalProcessingTime + "ms"));
-                Long lastProcessingTime = (Long) mBeanServer.getAttribute(contextMBean, "LastProcessingTime");
-                out.println(stringEscape.unescapeJava("\tLast Processing Time: " + lastProcessingTime + "ms"));
-                Long deltaProcessingTime = (Long) mBeanServer.getAttribute(contextMBean, "DeltaProcessingTime");
-                out.println(stringEscape.unescapeJava("\tDelta Processing Time: " + deltaProcessingTime + "ms"));
-
-                String load01 = (String) mBeanServer.getAttribute(contextMBean, "Load01");
-                String load05 = (String) mBeanServer.getAttribute(contextMBean, "Load05");
-                String load15 = (String) mBeanServer.getAttribute(contextMBean, "Load15");
-                out.println(stringEscape.unescapeJava("\tLoad Avg: " + load01 + ", " + load05 + ", " + load15));
-
-                // Test for null to see if a any exchanges have been processed first to avoid NPE
-                Object resetTimestampObj = mBeanServer.getAttribute(contextMBean, "ResetTimestamp");
-                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-                if (resetTimestampObj == null) {
-                    // Print an empty value for scripting
-                    out.println(stringEscape.unescapeJava("\tReset Statistics Date:"));
-                } else {
-                    Date firstExchangeTimestamp = (Date) resetTimestampObj;
-                    out.println(stringEscape.unescapeJava("\tReset Statistics Date: " + format.format(firstExchangeTimestamp)));
-                }
+        String xml = camelController.getCamelContextStatsAsXml(context, true, false);
+        if (xml != null) {
+            JAXBContext context = JAXBContext.newInstance(CamelContextStatDump.class);
+            Unmarshaller unmarshaller = context.createUnmarshaller();
+
+            CamelContextStatDump stat = (CamelContextStatDump) unmarshaller.unmarshal(new StringReader(xml));
+
+            long total = stat.getExchangesCompleted() + stat.getExchangesFailed();
+            out.println(stringEscape.unescapeJava("\tExchanges Total: " + total));
+            out.println(stringEscape.unescapeJava("\tExchanges Completed: " + stat.getExchangesCompleted()));
+            out.println(stringEscape.unescapeJava("\tExchanges Failed: " + stat.getExchangesFailed()));
+            out.println(stringEscape.unescapeJava("\tExchanges Inflight: " + stat.getExchangesInflight()));
+            out.println(stringEscape.unescapeJava("\tMin Processing Time: " + stat.getMinProcessingTime() + " ms"));
+            out.println(stringEscape.unescapeJava("\tMax Processing Time: " + stat.getMaxProcessingTime() + " ms"));
+            out.println(stringEscape.unescapeJava("\tMean Processing Time: " + stat.getMeanProcessingTime() + " ms"));
+            out.println(stringEscape.unescapeJava("\tTotal Processing Time: " + stat.getTotalProcessingTime() + " ms"));
+            out.println(stringEscape.unescapeJava("\tLast Processing Time: " + stat.getLastProcessingTime() + " ms"));
+            out.println(stringEscape.unescapeJava("\tDelta Processing Time: " + stat.getDeltaProcessingTime() + " ms"));
+
+            // Test for null to see if a any exchanges have been processed first to avoid NPE
+            if (isEmpty(stat.getResetTimestamp())) {
+                // Print an empty value for scripting
+                out.println(stringEscape.unescapeJava("\tReset Statistics Date:"));
+            } else {
+                Date date = new SimpleDateFormat(XML_TIMESTAMP_FORMAT).parse(stat.getResetTimestamp());
+                String text = new SimpleDateFormat(OUTPUT_TIMESTAMP_FORMAT).format(date);
+                out.println(stringEscape.unescapeJava("\tReset Statistics Date: " + text));
+            }
 
-                // Test for null to see if a any exchanges have been processed first to avoid NPE
-                Object firstExchangeTimestampObj = mBeanServer.getAttribute(contextMBean, "FirstExchangeCompletedTimestamp");
-                if (firstExchangeTimestampObj == null) {
-                    // Print an empty value for scripting
-                    out.println(stringEscape.unescapeJava("\tFirst Exchange Date:"));
-                } else {
-                    Date firstExchangeTimestamp = (Date) firstExchangeTimestampObj;
-                    out.println(stringEscape.unescapeJava("\tFirst Exchange Date: " + format.format(firstExchangeTimestamp)));
-                }
+            // Test for null to see if a any exchanges have been processed first to avoid NPE
+            if (isEmpty(stat.getFirstExchangeCompletedTimestamp())) {
+                // Print an empty value for scripting
+                out.println(stringEscape.unescapeJava("\tFirst Exchange Date:"));
+            } else {
+                Date date = new SimpleDateFormat(XML_TIMESTAMP_FORMAT).parse(stat.getFirstExchangeCompletedTimestamp());
+                String text = new SimpleDateFormat(OUTPUT_TIMESTAMP_FORMAT).format(date);
+                out.println(stringEscape.unescapeJava("\tFirst Exchange Date: " + text));
+            }
 
-                // Again, check for null to avoid NPE
-                Object lastExchangeCompletedTimestampObj = mBeanServer.getAttribute(contextMBean, "LastExchangeCompletedTimestamp");
-                if (lastExchangeCompletedTimestampObj == null) {
-                    // Print an empty value for scripting
-                    out.println(stringEscape.unescapeJava("\tLast Exchange Completed Date:"));
-                } else {
-                    Date lastExchangeCompletedTimestamp = (Date) lastExchangeCompletedTimestampObj;
-                    out.println(stringEscape.unescapeJava("\tLast Exchange Completed Date: " + format.format(lastExchangeCompletedTimestamp)));
-                }
+            // Test for null to see if a any exchanges have been processed first to avoid NPE
+            if (isEmpty(stat.getLastExchangeCompletedTimestamp())) {
+                // Print an empty value for scripting
+                out.println(stringEscape.unescapeJava("\tLast Exchange Date:"));
+            } else {
+                Date date = new SimpleDateFormat(XML_TIMESTAMP_FORMAT).parse(stat.getLastExchangeCompletedTimestamp());
+                String text = new SimpleDateFormat(OUTPUT_TIMESTAMP_FORMAT).format(date);
+                out.println(stringEscape.unescapeJava("\tLast Exchange Date: " + text));
+            }
 
+            // TODO: put that info in the controller
+            /*
                 // add type converter statistics if enabled
                 if (camelContext.getTypeConverterRegistry().getStatistics().isStatisticsEnabled()) {
                     out.println(stringEscape.unescapeJava(String.format("\tTypeConverterRegistry utilization: [attempts=%s, hits=%s, misses=%s, failures=%s]",
@@ -226,12 +208,7 @@ public class ContextInfoCommand extends AbstractCamelCommand {
 
                 out.println(stringEscape.unescapeJava("\tNumber of running routes: " + activeRoutes));
                 out.println(stringEscape.unescapeJava("\tNumber of not running routes: " + inactiveRoutes));
-            }
-
-        } else {
-            out.println("");
-            out.println(stringEscape.unescapeJava("\u001B[31mJMX Agent of Camel is not reachable. Maybe it has been disabled on the Camel context"));
-            out.println(stringEscape.unescapeJava("In consequence, some statistics are not available.\u001B[0m"));
+            }*/
         }
 
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RestRegistryListCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RestRegistryListCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RestRegistryListCommand.java
index a133119..8e43eea 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RestRegistryListCommand.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RestRegistryListCommand.java
@@ -72,8 +72,8 @@ public class RestRegistryListCommand extends AbstractContextCommand {
                 out.println(String.format(headerFormat, URL_COLUMN_NAME, BASE_PATH_LABEL, URI_TEMPLATE_LABEL, METHOD_COLUMN_LABEL, STATE_COLUMN_LABEL, ROUTE_COLUMN_LABEL));
                 out.println(String.format(headerFormat, "---", "---------", "------------", "------", "-----", "--------"));
             } else {
-                out.println(String.format(headerFormat, BASE_PATH_LABEL, URI_TEMPLATE_LABEL, METHOD_COLUMN_LABEL, STATE_COLUMN_LABEL));
-                out.println(String.format(headerFormat, "---------", "------------", "------", "-----"));
+                out.println(String.format(headerFormat, BASE_PATH_LABEL, URI_TEMPLATE_LABEL, METHOD_COLUMN_LABEL, STATE_COLUMN_LABEL, ROUTE_COLUMN_LABEL));
+                out.println(String.format(headerFormat, "---------", "------------", "------", "-----", "--------"));
             }
             for (Map<String, String> row : services) {
                 String uri = null;
@@ -167,11 +167,11 @@ public class RestRegistryListCommand extends AbstractContextCommand {
         int methodLen = Math.min(columnWidths.get(METHOD_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
         int statusLen = Math.min(columnWidths.get(STATE_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
         int routeLen = Math.min(columnWidths.get(ROUTE_COLUMN_LABEL) + columnWidthIncrement, getMaxColumnWidth());
-        basePathLen = Math.max(MIN_COLUMN_WIDTH, basePathLen);
         uriLen = Math.max(MIN_COLUMN_WIDTH, uriLen);
+        basePathLen = Math.max(MIN_COLUMN_WIDTH, basePathLen);
         uriTemplateLen = Math.max(MIN_COLUMN_WIDTH, uriTemplateLen);
         methodLen = Math.max(MIN_COLUMN_WIDTH, methodLen);
-        routeLen = Math.max(MIN_COLUMN_WIDTH, routeLen);
+        statusLen = Math.max(MIN_COLUMN_WIDTH, statusLen);
 
         // last row does not have min width
 

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RouteInfoCommand.java
----------------------------------------------------------------------
diff --git a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RouteInfoCommand.java b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RouteInfoCommand.java
index e02a9fa..24c1238 100644
--- a/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RouteInfoCommand.java
+++ b/platforms/commands/commands-core/src/main/java/org/apache/camel/commands/RouteInfoCommand.java
@@ -23,8 +23,11 @@ import java.util.Date;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Unmarshaller;
 
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.RouteStatDump;
 
+import static org.apache.camel.util.ObjectHelper.isEmpty;
+
 /**
  * Command to display detailed information about a Camel route.
  */
@@ -47,7 +50,7 @@ public class RouteInfoCommand extends AbstractRouteCommand {
 
     @Override
     public void executeOnRoute(CamelController camelController, String contextName, String routeId, PrintStream out, PrintStream err) throws Exception {
-        out.println(stringEscape.unescapeJava("\u001B[1m\u001B[33mCamel Route " + routeId + "\u001B[0m"));
+        out.println(stringEscape.unescapeJava("\u001B[1mCamel Route " + routeId + "\u001B[0m"));
         out.println(stringEscape.unescapeJava("\tCamel Context: " + contextName));
         out.println("");
         out.println(stringEscape.unescapeJava("\u001B[1mStatistics\u001B[0m"));
@@ -59,7 +62,8 @@ public class RouteInfoCommand extends AbstractRouteCommand {
 
             RouteStatDump route = (RouteStatDump) unmarshaller.unmarshal(new StringReader(xml));
 
-            out.println(stringEscape.unescapeJava("\tExchanges Total: " + route.getExchangesCompleted() + route.getExchangesFailed()));
+            long total = route.getExchangesCompleted() + route.getExchangesFailed();
+            out.println(stringEscape.unescapeJava("\tExchanges Total: " + total));
             out.println(stringEscape.unescapeJava("\tExchanges Completed: " + route.getExchangesCompleted()));
             out.println(stringEscape.unescapeJava("\tExchanges Failed: " + route.getExchangesFailed()));
             out.println(stringEscape.unescapeJava("\tExchanges Inflight: " + route.getExchangesInflight()));
@@ -71,7 +75,7 @@ public class RouteInfoCommand extends AbstractRouteCommand {
             out.println(stringEscape.unescapeJava("\tDelta Processing Time: " + route.getDeltaProcessingTime() + " ms"));
 
             // Test for null to see if a any exchanges have been processed first to avoid NPE
-            if (route.getResetTimestamp() == null) {
+            if (isEmpty(route.getResetTimestamp())) {
                 // Print an empty value for scripting
                 out.println(stringEscape.unescapeJava("\tReset Statistics Date:"));
             } else {
@@ -81,7 +85,7 @@ public class RouteInfoCommand extends AbstractRouteCommand {
             }
 
             // Test for null to see if a any exchanges have been processed first to avoid NPE
-            if (route.getFirstExchangeCompletedTimestamp() == null) {
+            if (isEmpty(route.getFirstExchangeCompletedTimestamp())) {
                 // Print an empty value for scripting
                 out.println(stringEscape.unescapeJava("\tFirst Exchange Date:"));
             } else {
@@ -91,7 +95,7 @@ public class RouteInfoCommand extends AbstractRouteCommand {
             }
 
             // Test for null to see if a any exchanges have been processed first to avoid NPE
-            if (route.getLastExchangeCompletedTimestamp() == null) {
+            if (isEmpty(route.getLastExchangeCompletedTimestamp())) {
                 // Print an empty value for scripting
                 out.println(stringEscape.unescapeJava("\tLast Exchange Date:"));
             } else {

http://git-wip-us.apache.org/repos/asf/camel/blob/a9eb7169/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInfo.java
----------------------------------------------------------------------
diff --git a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInfo.java b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInfo.java
index 690bee4..add0f4a 100644
--- a/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInfo.java
+++ b/platforms/karaf/commands/src/main/java/org/apache/camel/karaf/commands/ContextInfo.java
@@ -20,6 +20,7 @@ import org.apache.camel.commands.ContextInfoCommand;
 import org.apache.camel.commands.StringEscape;
 import org.apache.felix.gogo.commands.Argument;
 import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.Option;
 
 @Command(scope = "camel", name = "context-info", description = "Display detailed information about a Camel context.")
 public class ContextInfo extends CamelCommandSupport {
@@ -27,8 +28,9 @@ public class ContextInfo extends CamelCommandSupport {
     @Argument(index = 0, name = "name", description = "The name of the Camel context", required = true, multiValued = false)
     String name;
 
-    @Argument(index = 1, name = "mode", description = "Allows for different display modes (--verbose, etc)", required = false, multiValued = false)
-    String mode;
+    @Option(name = "--verbose", aliases = "-v", description = "Verbose output",
+            required = false, multiValued = false, valueToShowInHelp = "false")
+    boolean verbose;
 
     private StringEscape stringEscape;
 
@@ -38,7 +40,7 @@ public class ContextInfo extends CamelCommandSupport {
 
     @Override
     protected Object doExecute() throws Exception {
-        ContextInfoCommand command = new ContextInfoCommand(name, mode);
+        ContextInfoCommand command = new ContextInfoCommand(name, verbose);
         command.setStringEscape(stringEscape);
         return command.execute(camelController, System.out, System.err);
     }