Author: davsclaus
Date: Fri Jun  8 14:10:49 2012
New Revision: 1348081

URL: http://svn.apache.org/viewvc?rev=1348081&view=rev
Log:
CAMEL-5101: CamelContext MBean now has aggregated performance stats from the 
routes.

Added:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/CompositePerformanceCounter.java
    
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCanekContextExchangeStatisticsTest.java
      - copied, changed from r1347974, 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterExchangeStatisticsTest.java
Modified:
    
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationProcessor.java
    
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java?rev=1348081&r1=1348080&r2=1348081&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedCamelContextMBean.java
 Fri Jun  8 14:10:49 2012
@@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedOperation;
 
-public interface ManagedCamelContextMBean {
+public interface ManagedCamelContextMBean extends 
ManagedPerformanceCounterMBean {
 
     @ManagedAttribute(description = "Camel ID")
     String getCamelId();

Added: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/CompositePerformanceCounter.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/CompositePerformanceCounter.java?rev=1348081&view=auto
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/CompositePerformanceCounter.java
 (added)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/CompositePerformanceCounter.java
 Fri Jun  8 14:10:49 2012
@@ -0,0 +1,69 @@
+/**
+ * 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.management;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.api.management.PerformanceCounter;
+
+/**
+ * A composite {@link PerformanceCounter} is used for tracking performance 
statistics on both a per
+ * context and route level, by issuing callbacks on both when an event happens.
+ * <p/>
+ * This implementation is used so the {@link 
org.apache.camel.management.mbean.ManagedCamelContext}
+ * can aggregate all stats from the routes.
+ */
+public class CompositePerformanceCounter implements PerformanceCounter {
+
+    private final PerformanceCounter counter1;
+    private final PerformanceCounter counter2;
+
+    public CompositePerformanceCounter(PerformanceCounter counter1, 
PerformanceCounter counter2) {
+        this.counter1 = counter1;
+        this.counter2 = counter2;
+    }
+
+    @Override
+    public void completedExchange(Exchange exchange, long time) {
+        if (counter1.isStatisticsEnabled()) {
+            counter1.completedExchange(exchange, time);
+        }
+        if (counter2.isStatisticsEnabled()) {
+            counter2.completedExchange(exchange, time);
+        }
+    }
+
+    @Override
+    public void failedExchange(Exchange exchange) {
+        if (counter1.isStatisticsEnabled()) {
+            counter1.failedExchange(exchange);
+        }
+        if (counter2.isStatisticsEnabled()) {
+            counter2.failedExchange(exchange);
+        }
+    }
+
+    @Override
+    public boolean isStatisticsEnabled() {
+        // this method is not used
+        return true;
+    }
+
+    @Override
+    public void setStatisticsEnabled(boolean statisticsEnabled) {
+        // this method is not used
+    }
+}

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java?rev=1348081&r1=1348080&r2=1348081&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
 Fri Jun  8 14:10:49 2012
@@ -51,10 +51,12 @@ import org.apache.camel.impl.EndpointReg
 import org.apache.camel.impl.EventDrivenConsumerRoute;
 import org.apache.camel.impl.ProducerCache;
 import org.apache.camel.impl.ThrottlingInflightRoutePolicy;
+import org.apache.camel.management.mbean.ManagedCamelContext;
 import org.apache.camel.management.mbean.ManagedConsumerCache;
 import org.apache.camel.management.mbean.ManagedEndpoint;
 import org.apache.camel.management.mbean.ManagedEndpointRegistry;
 import org.apache.camel.management.mbean.ManagedProducerCache;
+import org.apache.camel.management.mbean.ManagedRoute;
 import org.apache.camel.management.mbean.ManagedService;
 import org.apache.camel.management.mbean.ManagedThrottlingInflightRoutePolicy;
 import org.apache.camel.management.mbean.ManagedTracer;
@@ -103,7 +105,8 @@ public class DefaultManagementLifecycleS
             new HashMap<Processor, KeyValueHolder<ProcessorDefinition<?>, 
InstrumentationProcessor>>();
     private final List<PreRegisterService> preServices = new 
ArrayList<PreRegisterService>();
     private final TimerListenerManager timerListenerManager = new 
TimerListenerManager();
-    private CamelContext camelContext;
+    private volatile CamelContext camelContext;
+    private volatile ManagedCamelContext camelContextMBean;
     private volatile boolean initialized;
     private final Set<String> knowRouteIds = new HashSet<String>();
     private final Map<Tracer, ManagedTracer> managedTracers = new 
HashMap<Tracer, ManagedTracer>();
@@ -183,6 +186,10 @@ public class DefaultManagementLifecycleS
         // yes we made it and are initialized
         initialized = true;
 
+        if (mc instanceof ManagedCamelContext) {
+            camelContextMBean = (ManagedCamelContext) mc;
+        }
+
         // register any pre registered now that we are initialized
         enlistPreRegisteredServices();
     }
@@ -251,6 +258,8 @@ public class DefaultManagementLifecycleS
         } catch (Exception e) {
             LOG.warn("Could not unregister CamelContext MBean", e);
         }
+
+        camelContextMBean = null;
     }
 
     public void onComponentAdd(String name, Component component) {
@@ -493,9 +502,17 @@ public class DefaultManagementLifecycleS
             if (route instanceof EventDrivenConsumerRoute) {
                 EventDrivenConsumerRoute edcr = (EventDrivenConsumerRoute) 
route;
                 Processor processor = edcr.getProcessor();
-                if (processor instanceof InstrumentationProcessor) {
+                if (processor instanceof InstrumentationProcessor && mr 
instanceof ManagedRoute) {
                     InstrumentationProcessor ip = (InstrumentationProcessor) 
processor;
-                    ip.setCounter(mr);
+                    ManagedRoute routeMBean = (ManagedRoute) mr;
+
+                    // we need to wrap the counter with the camel context so 
we get stats updated on the context as well
+                    if (camelContextMBean != null) {
+                        CompositePerformanceCounter wrapper = new 
CompositePerformanceCounter(routeMBean, camelContextMBean);
+                        ip.setCounter(wrapper);
+                    } else {
+                        ip.setCounter(routeMBean);
+                    }
                 }
             }
 

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationProcessor.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationProcessor.java?rev=1348081&r1=1348080&r2=1348081&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationProcessor.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/InstrumentationProcessor.java
 Fri Jun  8 14:10:49 2012
@@ -58,8 +58,10 @@ public class InstrumentationProcessor ex
 
         if (this.counter instanceof DelegatePerformanceCounter) {
             ((DelegatePerformanceCounter) this.counter).setCounter(mpc);
-        } else {
+        } else if (mpc != null) {
             this.counter = mpc;
+        } else if (counter instanceof PerformanceCounter) {
+            this.counter = (PerformanceCounter) counter;
         }
     }
 

Modified: 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java?rev=1348081&r1=1348080&r2=1348081&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
 (original)
+++ 
camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
 Fri Jun  8 14:10:49 2012
@@ -30,6 +30,7 @@ import javax.management.ObjectName;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
+import org.apache.camel.ManagementStatisticsLevel;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.TimerListener;
 import org.apache.camel.api.management.ManagedResource;
@@ -40,22 +41,19 @@ import org.apache.camel.model.ModelCamel
 import org.apache.camel.model.ModelHelper;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RoutesDefinition;
-import org.apache.camel.spi.ManagementStrategy;
 
 /**
  * @version 
  */
 @ManagedResource(description = "Managed CamelContext")
-public class ManagedCamelContext implements TimerListener, 
ManagedCamelContextMBean {
+public class ManagedCamelContext extends ManagedPerformanceCounter implements 
TimerListener, ManagedCamelContextMBean {
     private final ModelCamelContext context;   
     private final LoadTriplet load = new LoadTriplet();
 
     public ManagedCamelContext(ModelCamelContext context) {
         this.context = context;
-    }
-
-    public void init(ManagementStrategy strategy) {
-        // do nothing
+        boolean enabled = context.getManagementStrategy().getStatisticsLevel() 
!= ManagementStatisticsLevel.Off;
+        setStatisticsEnabled(enabled);
     }
 
     public CamelContext getContext() {
@@ -241,7 +239,10 @@ public class ManagedCamelContext impleme
     @Override
     public String dumpRoutesStatsAsXml(boolean fullStats, boolean 
includeProcessors) throws Exception {
         StringBuilder sb = new StringBuilder();
-        sb.append("<camelContextStat").append(String.format(" id=\"%s\"", 
getCamelId())).append(">\n");
+        sb.append("<camelContextStat").append(String.format(" id=\"%s\"", 
getCamelId()));
+        // use substring as we only want the attributes
+        String stat = dumpStatsAsXml(fullStats);
+        sb.append(" ").append(stat.substring(7, stat.length() - 
2)).append(">\n");
 
         MBeanServer server = 
getContext().getManagementStrategy().getManagementAgent().getMBeanServer();
         if (server != null) {
@@ -266,7 +267,7 @@ public class ManagedCamelContext impleme
                 ManagedRouteMBean route = 
MBeanServerInvocationHandler.newProxyInstance(server, on, 
ManagedRouteMBean.class, true);
                 sb.append("    <routeStat").append(String.format(" id=\"%s\"", 
route.getRouteId()));
                 // use substring as we only want the attributes
-                String stat = route.dumpStatsAsXml(fullStats);
+                stat = route.dumpStatsAsXml(fullStats);
                 sb.append(" ").append(stat.substring(7, stat.length() - 
2)).append(">\n");
 
                 // add processor details if needed

Copied: 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCanekContextExchangeStatisticsTest.java
 (from r1347974, 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterExchangeStatisticsTest.java)
URL: 
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCanekContextExchangeStatisticsTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCanekContextExchangeStatisticsTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterExchangeStatisticsTest.java&r1=1347974&r2=1348081&rev=1348081&view=diff
==============================================================================
--- 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRegisterExchangeStatisticsTest.java
 (original)
+++ 
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedCanekContextExchangeStatisticsTest.java
 Fri Jun  8 14:10:49 2012
@@ -24,23 +24,50 @@ import org.apache.camel.builder.RouteBui
 /**
  * @version 
  */
-public class ManagedRegisterExchangeStatisticsTest extends 
ManagementTestSupport {
+public class ManagedCanekContextExchangeStatisticsTest extends 
ManagementTestSupport {
 
     public void testExchangesCompletedStatistics() throws Exception {
         MBeanServer mbeanServer = getMBeanServer();
 
-        ObjectName on = 
ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=routes,name=\"route1\"");
+        ObjectName on = 
ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=context,name=\"camel-1\"");
         Long completed = (Long) mbeanServer.getAttribute(on, 
"ExchangesCompleted");
         assertEquals(0, completed.longValue());
 
-        getMockEndpoint("mock:result").expectedMessageCount(1);
+        ObjectName route1 = 
ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=routes,name=\"route1\"");
+        Long completed1 = (Long) mbeanServer.getAttribute(route1, 
"ExchangesCompleted");
+        assertEquals(0, completed1.longValue());
+
+        ObjectName route2 = 
ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=routes,name=\"route2\"");
+        Long completed2 = (Long) mbeanServer.getAttribute(route1, 
"ExchangesCompleted");
+        assertEquals(0, completed2.longValue());
 
+        getMockEndpoint("mock:result").expectedMessageCount(1);
         template.sendBody("direct:start", "Hello World");
+        assertMockEndpointsSatisfied();
+
+        completed = (Long) mbeanServer.getAttribute(route1, 
"ExchangesCompleted");
+        assertEquals(1, completed.longValue());
 
+        completed1 = (Long) mbeanServer.getAttribute(route1, 
"ExchangesCompleted");
+        assertEquals(1, completed1.longValue());
+
+        completed2 = (Long) mbeanServer.getAttribute(route2, 
"ExchangesCompleted");
+        assertEquals(0, completed2.longValue());
+
+        resetMocks();
+        getMockEndpoint("mock:result").expectedMessageCount(2);
+        template.sendBody("direct:start", "Hi World");
+        template.sendBody("direct:bar", "Bye World");
         assertMockEndpointsSatisfied();
 
         completed = (Long) mbeanServer.getAttribute(on, "ExchangesCompleted");
-        assertEquals(1, completed.longValue());
+        assertEquals(3, completed.longValue());
+
+        completed1 = (Long) mbeanServer.getAttribute(route1, 
"ExchangesCompleted");
+        assertEquals(2, completed1.longValue());
+
+        completed2 = (Long) mbeanServer.getAttribute(route2, 
"ExchangesCompleted");
+        assertEquals(1, completed2.longValue());
     }
 
     @Override
@@ -48,7 +75,13 @@ public class ManagedRegisterExchangeStat
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:start").to("log:foo").to("mock:result");
+                from("direct:start")
+                    .routeId("route1")
+                    .to("log:foo").to("mock:result");
+
+                from("direct:bar")
+                    .routeId("route2")
+                    .to("log:bar").to("mock:result");
             }
         };
     }


Reply via email to