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 2012/04/16 09:10:04 UTC

svn commit: r1326514 - in /camel/trunk/camel-core/src: main/java/org/apache/camel/api/management/mbean/ main/java/org/apache/camel/impl/converter/ main/java/org/apache/camel/management/ main/java/org/apache/camel/management/mbean/ main/java/org/apache/...

Author: davsclaus
Date: Mon Apr 16 07:10:04 2012
New Revision: 1326514

URL: http://svn.apache.org/viewvc?rev=1326514&view=rev
Log:
CAMEL-5175: Added utilization stats to type converter registry which is also accessible from JMX.

Added:
    camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java
    camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java
      - copied, changed from r1326471, camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedLoadBalancerTest.java
Modified:
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/management/DefaultManagementLifecycleStrategy.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java?rev=1326514&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/api/management/mbean/ManagedTypeConverterRegistryMBean.java Mon Apr 16 07:10:04 2012
@@ -0,0 +1,42 @@
+/**
+ * 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.api.management.mbean;
+
+import org.apache.camel.api.management.ManagedAttribute;
+import org.apache.camel.api.management.ManagedOperation;
+
+/**
+ *
+ */
+public interface ManagedTypeConverterRegistryMBean extends ManagedServiceMBean {
+
+    @ManagedAttribute(description = "Number of type conversion attempts")
+    long getAttemptCounter();
+
+    @ManagedAttribute(description = "Number of type conversion hits (successful conversions)")
+    long getHitCounter();
+
+    @ManagedAttribute(description = "Number of type conversion misses (no suitable type converter)")
+    long getMissCounter();
+
+    @ManagedAttribute(description = "Number of type conversion failures (failed conversions)")
+    long getFailedCounter();
+
+    @ManagedOperation(description = "Resets the type conversion counters")
+    void resetTypeConversionCounters();
+
+}

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java?rev=1326514&r1=1326513&r2=1326514&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java Mon Apr 16 07:10:04 2012
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.camel.CamelExecutionException;
 import org.apache.camel.Exchange;
@@ -41,7 +42,6 @@ import org.apache.camel.spi.TypeConverte
 import org.apache.camel.spi.TypeConverterRegistry;
 import org.apache.camel.support.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -61,6 +61,11 @@ public abstract class BaseTypeConverterR
     protected Injector injector;
     protected final FactoryFinder factoryFinder;
     protected final PropertyEditorTypeConverter propertyEditorTypeConverter = new PropertyEditorTypeConverter();
+    protected final Statistics statistics = new UtilizationStatistics();
+    protected final AtomicLong attemptCounter = new AtomicLong();
+    protected final AtomicLong missCounter = new AtomicLong();
+    protected final AtomicLong hitCounter = new AtomicLong();
+    protected final AtomicLong failedCounter = new AtomicLong();
 
     public BaseTypeConverterRegistry(PackageScanClassResolver resolver, Injector injector, FactoryFinder factoryFinder) {
         this.resolver = resolver;
@@ -102,8 +107,10 @@ public abstract class BaseTypeConverterR
 
         Object answer;
         try {
+            attemptCounter.incrementAndGet();
             answer = doConvertTo(type, exchange, value, false);
         } catch (Exception e) {
+            failedCounter.incrementAndGet();
             // if its a ExecutionException then we have rethrow it as its not due to failed conversion
             // this is special for FutureTypeConverter
             boolean execution = ObjectHelper.getException(ExecutionException.class, e) != null
@@ -117,8 +124,11 @@ public abstract class BaseTypeConverterR
         }
         if (answer == Void.TYPE) {
             // Could not find suitable conversion
+            missCounter.incrementAndGet();
+            // Could not find suitable conversion
             return null;
         } else {
+            hitCounter.incrementAndGet();
             return (T) answer;
         }
     }
@@ -137,15 +147,20 @@ public abstract class BaseTypeConverterR
 
         Object answer;
         try {
+            attemptCounter.incrementAndGet();
             answer = doConvertTo(type, exchange, value, false);
         } catch (Exception e) {
+            failedCounter.incrementAndGet();
             // error occurred during type conversion
             throw new TypeConversionException(value, type, e);
         }
         if (answer == Void.TYPE || value == null) {
             // Could not find suitable conversion
+            missCounter.incrementAndGet();
+            // Could not find suitable conversion
             throw new NoTypeConversionAvailableException(value, type);
         } else {
+            hitCounter.incrementAndGet();
             return (T) answer;
         }
     }
@@ -452,15 +467,66 @@ public abstract class BaseTypeConverterR
     }
 
     @Override
+    public Statistics getStatistics() {
+        return statistics;
+    }
+
+    @Override
     protected void doStart() throws Exception {
         // noop
     }
 
     @Override
     protected void doStop() throws Exception {
+        // log utilization statistics when stopping, including mappings
+        String info = statistics.toString();
+        info += String.format(" mappings[total=%s, misses=%s]", typeMappings.size(), misses.size());
+        log.info(info);
+
         typeMappings.clear();
         misses.clear();
         propertyEditorTypeConverter.clear();
+        statistics.reset();
+    }
+
+    /**
+     * Represents utilization statistics
+     */
+    private final class UtilizationStatistics implements Statistics {
+
+        @Override
+        public long getAttemptCounter() {
+            return attemptCounter.get();
+        }
+
+        @Override
+        public long getHitCounter() {
+            return hitCounter.get();
+        }
+
+        @Override
+        public long getMissCounter() {
+            return missCounter.get();
+        }
+
+        @Override
+        public long getFailedCounter() {
+            return failedCounter.get();
+        }
+
+        @Override
+        public void reset() {
+            attemptCounter.set(0);
+            hitCounter.set(0);
+            missCounter.set(0);
+            failedCounter.set(0);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("TypeConverterRegistry utilization[attempts=%s, hits=%s, misses=%s, failures=%s]",
+                    getAttemptCounter(), getHitCounter(), getMissCounter(), getFailedCounter());
+        }
     }
 
     /**

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=1326514&r1=1326513&r2=1326514&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 Mon Apr 16 07:10:04 2012
@@ -58,6 +58,7 @@ import org.apache.camel.management.mbean
 import org.apache.camel.management.mbean.ManagedService;
 import org.apache.camel.management.mbean.ManagedThrottlingInflightRoutePolicy;
 import org.apache.camel.management.mbean.ManagedTracer;
+import org.apache.camel.management.mbean.ManagedTypeConverterRegistry;
 import org.apache.camel.model.AOPDefinition;
 import org.apache.camel.model.InterceptDefinition;
 import org.apache.camel.model.OnCompletionDefinition;
@@ -75,6 +76,7 @@ import org.apache.camel.spi.ManagementNa
 import org.apache.camel.spi.ManagementObjectStrategy;
 import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.spi.RouteContext;
+import org.apache.camel.spi.TypeConverterRegistry;
 import org.apache.camel.spi.UnitOfWork;
 import org.apache.camel.support.ServiceSupport;
 import org.apache.camel.support.TimerListenerManager;
@@ -418,6 +420,8 @@ public class DefaultManagementLifecycleS
             answer = new ManagedProducerCache(context, (ProducerCache) service);
         } else if (service instanceof EndpointRegistry) {
             answer = new ManagedEndpointRegistry(context, (EndpointRegistry) service);
+        } else if (service instanceof TypeConverterRegistry) {
+            answer = new ManagedTypeConverterRegistry(context, (TypeConverterRegistry) service);
         } else if (service != null) {
             // fallback as generic service
             answer = getManagementObjectStrategy().getManagedObjectForService(context, service);

Added: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java?rev=1326514&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedTypeConverterRegistry.java Mon Apr 16 07:10:04 2012
@@ -0,0 +1,60 @@
+/**
+ * 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.mbean;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.api.management.mbean.ManagedTypeConverterRegistryMBean;
+import org.apache.camel.spi.TypeConverterRegistry;
+
+/**
+ *
+ */
+@ManagedResource(description = "Managed TypeConverterRegistry")
+public class ManagedTypeConverterRegistry extends ManagedService implements ManagedTypeConverterRegistryMBean {
+
+    private final TypeConverterRegistry registry;
+
+    public ManagedTypeConverterRegistry(CamelContext context, TypeConverterRegistry registry) {
+        super(context, registry);
+        this.registry = registry;
+    }
+
+    public TypeConverterRegistry getRegistry() {
+        return registry;
+    }
+
+    public long getAttemptCounter() {
+        return registry.getStatistics().getAttemptCounter();
+    }
+
+    public long getHitCounter() {
+        return registry.getStatistics().getHitCounter();
+    }
+
+    public long getMissCounter() {
+        return registry.getStatistics().getMissCounter();
+    }
+
+    public long getFailedCounter() {
+        return registry.getStatistics().getFailedCounter();
+    }
+
+    public void resetTypeConversionCounters() {
+        registry.getStatistics().reset();
+    }
+}

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java?rev=1326514&r1=1326513&r2=1326514&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/spi/TypeConverterRegistry.java Mon Apr 16 07:10:04 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.spi;
 
+import org.apache.camel.Service;
 import org.apache.camel.TypeConverter;
 
 /**
@@ -23,7 +24,38 @@ import org.apache.camel.TypeConverter;
  *
  * @version 
  */
-public interface TypeConverterRegistry {
+public interface TypeConverterRegistry extends Service {
+
+    /**
+     * Utilization statistics of the this registry.
+     */
+    interface Statistics {
+
+        /**
+         * Number of attempts
+         */
+        long getAttemptCounter();
+
+        /**
+         * Number of successful conversions
+         */
+        long getHitCounter();
+
+        /**
+         * Number of attempts which cannot be converted as no suitable type converter exists
+         */
+        long getMissCounter();
+
+        /**
+         * Number of failed attempts during type conversion
+         */
+        long getFailedCounter();
+
+        /**
+         * Reset the counters
+         */
+        void reset();
+    }
 
     /**
      * Registers a new type converter
@@ -64,4 +96,12 @@ public interface TypeConverterRegistry {
      * @return the injector
      */
     Injector getInjector();
+
+    /**
+     * Gets the utilization statistics of this type converter registry
+     *
+     * @return the utilization statistics
+     */
+    Statistics getStatistics();
+
 }

Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java (from r1326471, camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedLoadBalancerTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedLoadBalancerTest.java&r1=1326471&r2=1326514&rev=1326514&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedLoadBalancerTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedTypeConverterRegistryTest.java Mon Apr 16 07:10:04 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.management;
 
+import java.util.Set;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
@@ -24,33 +25,64 @@ import org.apache.camel.builder.RouteBui
 /**
  * @version 
  */
-public class ManagedLoadBalancerTest extends ManagementTestSupport {
+public class ManagedTypeConverterRegistryTest extends ManagementTestSupport {
 
-    public void testLoadBalancer() throws Exception {
-        getMockEndpoint("mock:a").expectedBodiesReceived("Hello World", "Hi World");
-        getMockEndpoint("mock:b").expectedBodiesReceived("Bye World");
-
-        template.sendBody("direct:start", "Hello World");
-        template.sendBody("direct:start", "Bye World");
-        template.sendBody("direct:start", "Hi World");
+    public void testTypeConverterRegistry() throws Exception {
+        getMockEndpoint("mock:a").expectedMessageCount(2);
+
+        template.sendBody("direct:start", "3");
+        template.sendBody("direct:start", "7");
 
         assertMockEndpointsSatisfied();
 
         MBeanServer mbeanServer = getMBeanServer();
 
-        ObjectName name = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=endpoints,name=\"mock://a\"");
-        Long queueSize = (Long) mbeanServer.invoke(name, "queueSize", null, null);
-        assertEquals(2, queueSize.intValue());
-
-        name = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=endpoints,name=\"mock://b\"");
-        queueSize = (Long) mbeanServer.invoke(name, "queueSize", null, null);
-        assertEquals(1, queueSize.intValue());
-
-        name = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=processors,name=\"myBalancer\"");
-        mbeanServer.isRegistered(name);
-        
-        Long total = (Long) mbeanServer.getAttribute(name, "ExchangesTotal");
-        assertEquals(3, total.intValue());
+        ObjectName on = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=services,*");
+
+        // number of services
+        Set<ObjectName> names = mbeanServer.queryNames(on, null);
+        ObjectName name = null;
+        for (ObjectName service : names) {
+            if (service.toString().contains("DefaultTypeConverter")) {
+                name = service;
+                break;
+            }
+        }
+        assertNotNull("Cannot find DefaultTypeConverter", name);
+
+        Long failed = (Long) mbeanServer.getAttribute(name, "FailedCounter");
+        assertEquals(0, failed.intValue());
+        Long miss = (Long) mbeanServer.getAttribute(name, "MissCounter");
+        assertEquals(0, miss.intValue());
+        Long attempt = (Long) mbeanServer.getAttribute(name, "AttemptCounter");
+        assertEquals(2, attempt.intValue());
+        Long hit = (Long) mbeanServer.getAttribute(name, "HitCounter");
+        assertEquals(2, hit.intValue());
+
+        try {
+            template.sendBody("direct:start", "foo");
+            fail("Should have thrown exception");
+        } catch (Exception e) {
+            // expected
+        }
+
+        // should now have a failed
+        failed = (Long) mbeanServer.getAttribute(name, "FailedCounter");
+        assertEquals(1, failed.intValue());
+        miss = (Long) mbeanServer.getAttribute(name, "MissCounter");
+        assertEquals(0, miss.intValue());
+
+        // reset
+        mbeanServer.invoke(name, "resetTypeConversionCounters", null, null);
+
+        failed = (Long) mbeanServer.getAttribute(name, "FailedCounter");
+        assertEquals(0, failed.intValue());
+        miss = (Long) mbeanServer.getAttribute(name, "MissCounter");
+        assertEquals(0, miss.intValue());
+        attempt = (Long) mbeanServer.getAttribute(name, "AttemptCounter");
+        assertEquals(0, attempt.intValue());
+        hit = (Long) mbeanServer.getAttribute(name, "HitCounter");
+        assertEquals(0, hit.intValue());
     }
 
     @Override
@@ -59,8 +91,8 @@ public class ManagedLoadBalancerTest ext
             @Override
             public void configure() throws Exception {
                 from("direct:start").routeId("foo")
-                    .loadBalance().id("myBalancer").roundRobin()
-                        .to("mock:a").to("mock:b");
+                    .convertBodyTo(int.class)
+                    .to("mock:a");
             }
         };
     }