Author: davsclaus
Date: Fri Dec 31 10:00:22 2010
New Revision: 1054080

URL: http://svn.apache.org/viewvc?rev=1054080&view=rev
Log:
CAMEL-1397: Added some basic route statistics to web console. Thanks to Ben for 
patch.

Added:
    
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java
    
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java
    
camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java
Modified:
    
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java
    
camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp

Modified: 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java?rev=1054080&r1=1054079&r2=1054080&view=diff
==============================================================================
--- 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java
 (original)
+++ 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/model/Route.java
 Fri Dec 31 10:00:22 2010
@@ -20,6 +20,8 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.ServiceStatus;
 import org.apache.camel.model.DescriptionDefinition;
 import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.web.util.JMXRouteStatistics;
+import org.apache.camel.web.util.RouteStatistics;
 
 /**
  * Represents a route.
@@ -29,6 +31,7 @@ import org.apache.camel.model.RouteDefin
 public class Route {
     private CamelContext camelContext;
     private RouteDefinition route;
+    private final RouteStatistics statistics = new JMXRouteStatistics();
 
     public Route() {
     }
@@ -66,4 +69,13 @@ public class Route {
     public boolean isStoppable() {
         return route.isStoppable(camelContext);
     }
+    
+    public Object getStatistic(String attribute) {
+        Object answer = statistics.getRouteStatistic(camelContext, 
route.getId(), attribute);
+        if (answer == null) {
+            // we don't want null on web pages so we return an empty string
+            return "";
+        }
+        return answer;
+    }
 }

Added: 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java?rev=1054080&view=auto
==============================================================================
--- 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java
 (added)
+++ 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/JMXRouteStatistics.java
 Fri Dec 31 10:00:22 2010
@@ -0,0 +1,76 @@
+/**
+ * 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.web.util;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.management.ManagedManagementStrategy;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Gathers {...@link RouteStatistics} from JMX.
+ * <p/>
+ * If JMX is disabled then no statistics can be gathered, and <tt>null</tt> is 
returned.
+ */
+public class JMXRouteStatistics implements RouteStatistics {
+
+    private static final Log LOG = LogFactory.getLog(JMXRouteStatistics.class);
+
+    @SuppressWarnings("unchecked")
+    public Object getRouteStatistic(CamelContext camelContext, String routeID, 
String attribute) {
+        // only possible if JMX is enabled
+        if (!(camelContext.getManagementStrategy() instanceof 
ManagedManagementStrategy)) {
+            return null;
+        }
+
+        try {
+            MBeanServer server = 
camelContext.getManagementStrategy().getManagementAgent().getMBeanServer();
+            String domain = 
camelContext.getManagementStrategy().getManagementAgent().getMBeanObjectDomainName();
+
+            ObjectName objName = new ObjectName(domain + ":type=routes,*");
+            List<ObjectName> cacheList = new 
LinkedList(server.queryNames(objName, null));
+            for (Iterator<ObjectName> iter = cacheList.iterator(); 
iter.hasNext();) {
+                objName = iter.next();
+                String keyProps = objName.getCanonicalKeyPropertyListString();
+                ObjectName objectInfoName = new ObjectName(domain + ":" + 
keyProps);
+                String currentRouteID = (String) 
server.getAttribute(objectInfoName, "RouteId");
+                if (currentRouteID.equals(routeID)) {
+                    Object value = server.getAttribute(objectInfoName, 
attribute);
+                    if (value instanceof Date) {
+                        DateFormat df = 
DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
+                        return df.format(value);
+                    } else {
+                        return value;
+                    }
+                }
+            }
+        } catch (Exception e) {
+            LOG.warn("Error getting route statistic from JMX. This exception 
will be ignored.", e);
+        }
+
+        return null;
+    }
+
+}

Added: 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java?rev=1054080&view=auto
==============================================================================
--- 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java
 (added)
+++ 
camel/trunk/components/camel-web/src/main/java/org/apache/camel/web/util/RouteStatistics.java
 Fri Dec 31 10:00:22 2010
@@ -0,0 +1,35 @@
+/**
+ * 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.web.util;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * @version $Revision$
+ */
+public interface RouteStatistics {
+
+    /**
+     * Gets statistic for the given route
+     *
+     * @param camelContext the context in question
+     * @param routeID      the routeID to retrieve stats for
+     * @param attribute    the attribute to retrieve
+     * @return the statistic, or <tt>null</tt> if not possible to find or get 
the statistic
+     */
+    Object getRouteStatistic(CamelContext camelContext, String routeID, String 
attribute);
+}

Modified: 
camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp?rev=1054080&r1=1054079&r2=1054080&view=diff
==============================================================================
--- 
camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp
 (original)
+++ 
camel/trunk/components/camel-web/src/main/webapp/WEB-INF/org/apache/camel/web/resources/RoutesResource.index.ssp
 Fri Dec 31 10:00:22 2010
@@ -10,6 +10,9 @@
     <th>Route</th>
     <th colspan="2">Status</th>
     <th>Remove</th>
+    <th>Exchanges (Completed/Failed/Inflight)</th>
+    <th>Processing Time (Min/Max/Mean)</th>
+    <th>Message Time (First/Last)</th>
   </tr>
 <ul>
   #for(i <- it.getRoutes)
@@ -40,6 +43,15 @@
                <a href='${uri("/routes/" + i.getId + "/remove")}'>remove</a>
        #end
     </td>
+    <td>
+      ${i.getStatistic("ExchangesCompleted")} / 
${i.getStatistic("ExchangesFailed")} / ${i.getStatistic("InflightExchanges")}
+    </td>
+    <td>
+      ${i.getStatistic("MinProcessingTime")} / 
${i.getStatistic("MaxProcessingTime")} / ${i.getStatistic("MeanProcessingTime")}
+    </td>
+    <td>
+      ${i.getStatistic("FirstExchangeCompletedTimestamp")} / 
${i.getStatistic("LastExchangeCompletedTimestamp")}
+    </td>
   </tr>
   #end
 </ul>

Added: 
camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java?rev=1054080&view=auto
==============================================================================
--- 
camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java
 (added)
+++ 
camel/trunk/components/camel-web/src/test/java/org/apache/camel/web/util/JMXRouteStatisticsTest.java
 Fri Dec 31 10:00:22 2010
@@ -0,0 +1,72 @@
+/**
+ * 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.web.util;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.util.CastUtils;
+import org.apache.camel.web.resources.CamelContextResource;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.FileSystemXmlApplicationContext;
+
+public class JMXRouteStatisticsTest extends Assert {
+    private AbstractXmlApplicationContext applicationContext;
+    private CamelContext camelContext;
+    private RouteStatistics statistics = new JMXRouteStatistics();
+ 
+    @Test
+    public void testRouteStats() throws Exception {
+        CamelContextResource resource = new CamelContextResource(camelContext);
+        RoutesDefinition routes = 
resource.getRoutesResource().getRouteDefinitions();
+        List<RouteDefinition> list = routes.getRoutes();
+        Object exchangesCompleted = statistics.getRouteStatistic(camelContext, 
list.get(0).getId(), "ExchangesCompleted");
+        assertEquals("JMX value incorrect, should be 0", new Long(0), 
exchangesCompleted);
+        
+        ProducerTemplate template = camelContext.createProducerTemplate();
+        template.sendBody("seda:foo", "test");
+        
+        Thread.sleep(100);
+        
+        exchangesCompleted = statistics.getRouteStatistic(camelContext, 
list.get(0).getId(), "ExchangesCompleted");
+        assertEquals("JMX value incorrect, should be 1", new Long(1), 
exchangesCompleted);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        applicationContext = new 
FileSystemXmlApplicationContext("src/main/webapp/WEB-INF/applicationContext.xml");
+        applicationContext.start();
+        Map<String, CamelContext> beansOfType = 
CastUtils.cast(applicationContext.getBeansOfType(CamelContext.class));
+        camelContext = beansOfType.isEmpty() ? null : 
beansOfType.values().iterator().next();
+        assertNotNull("camelContext", camelContext);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (applicationContext != null) {
+            applicationContext.stop();
+        }
+    }
+}


Reply via email to