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");
}
};
}