diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/SimpleMessageHandlerMetrics.java b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/SimpleMessageHandlerMetrics.java index 89e0918d1b..8f9875f1d9 100644 --- a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/SimpleMessageHandlerMetrics.java +++ b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/SimpleMessageHandlerMetrics.java @@ -22,9 +22,7 @@ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.integration.Message; -import org.springframework.integration.MessagingException; import org.springframework.integration.core.MessageHandler; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.util.StopWatch; @@ -85,13 +83,13 @@ public class SimpleMessageHandlerMetrics implements MethodInterceptor, MessageHa String method = invocation.getMethod().getName(); if ("handleMessage".equals(method)) { Message message = (Message) invocation.getArguments()[0]; - handleMessage(message); + handleMessage(invocation, message); return null; } return invocation.proceed(); } - private void handleMessage(Message message) throws MessagingException { + private void handleMessage(MethodInvocation invocation, Message message) throws Throwable { if (logger.isTraceEnabled()) { logger.trace("messageHandler(" + this.handler + ") message(" + message + ") :"); } @@ -105,16 +103,12 @@ public class SimpleMessageHandlerMetrics implements MethodInterceptor, MessageHa this.handleCount.incrementAndGet(); this.activeCount.incrementAndGet(); - this.handler.handleMessage(message); + invocation.proceed(); timer.stop(); this.duration.append(timer.getTotalTimeMillis()); } - catch (RuntimeException e) { - this.errorCount.incrementAndGet(); - throw e; - } - catch (Error e) { + catch (Throwable e) { this.errorCount.incrementAndGet(); throw e; } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/MessageMetricsAdviceTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/MessageMetricsAdviceTests.java new file mode 100644 index 0000000000..7d5d01c994 --- /dev/null +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/MessageMetricsAdviceTests.java @@ -0,0 +1,127 @@ +package org.springframework.integration.monitor; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; +import org.junit.Before; +import org.junit.Test; +import org.springframework.aop.framework.Advised; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.support.NameMatchMethodPointcutAdvisor; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.integration.Message; +import org.springframework.integration.MessageChannel; +import org.springframework.integration.MessagingException; +import org.springframework.integration.channel.NullChannel; +import org.springframework.integration.core.MessageHandler; +import org.springframework.integration.monitor.IntegrationMBeanExporter; +import org.springframework.integration.support.MessageBuilder; +import org.springframework.util.ClassUtils; + +/** + * @author Tareq Abedrabbo + * @author Dave Syer + * @since 2.0.4 + */ +public class MessageMetricsAdviceTests { + + private IntegrationMBeanExporter mBeanExporter; + + private MessageHandler handler; + + private MessageChannel channel; + + @Before + public void setUp() throws Exception { + channel = new NullChannel(); + mBeanExporter = new IntegrationMBeanExporter(); + mBeanExporter.setBeanFactory(new DefaultListableBeanFactory()); + mBeanExporter.setBeanClassLoader(ClassUtils.getDefaultClassLoader()); + mBeanExporter.afterPropertiesSet(); + handler = new DummyHandler(); + } + + @Test + public void adviceExportedHandler() throws Exception { + Advised advised = (Advised) mBeanExporter.postProcessAfterInitialization(handler, "test"); + + DummyInterceptor interceptor = new DummyInterceptor(); + advised.addAdvice(interceptor); + + assertThat(advised.getAdvisors().length, equalTo(2)); + + ((MessageHandler) advised).handleMessage(MessageBuilder.withPayload("test").build()); + assertThat(interceptor.invoked, is(true)); + } + + @Test + public void exportAdvisedHandler() throws Exception { + + DummyInterceptor interceptor = new DummyInterceptor(); + NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor(interceptor); + advisor.addMethodName("handleMessage"); + + ProxyFactory factory = new ProxyFactory(handler); + factory.addAdvisor(advisor); + MessageHandler advised = (MessageHandler) factory.getProxy(); + + MessageHandler exported = (MessageHandler) mBeanExporter.postProcessAfterInitialization(advised, "test"); + exported.handleMessage(MessageBuilder.withPayload("test").build()); + } + + @Test + public void adviceExportedChannel() throws Exception { + Advised advised = (Advised) mBeanExporter.postProcessAfterInitialization(channel, "testChannel"); + + DummyInterceptor interceptor = new DummyInterceptor(); + advised.addAdvice(interceptor); + + assertThat(advised.getAdvisors().length, equalTo(2)); + + ((MessageChannel) advised).send(MessageBuilder.withPayload("test").build()); + assertThat(interceptor.invoked, is(true)); + } + + @Test + public void exportAdvisedChannel() throws Exception { + + DummyInterceptor interceptor = new DummyInterceptor(); + NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor(interceptor); + advisor.addMethodName("send"); + + ProxyFactory factory = new ProxyFactory(channel); + factory.addAdvisor(advisor); + MessageChannel advised = (MessageChannel) factory.getProxy(); + + MessageChannel exported = (MessageChannel) mBeanExporter.postProcessAfterInitialization(advised, "test"); + exported.send(MessageBuilder.withPayload("test").build()); + } + + private static class DummyHandler implements MessageHandler { + + @SuppressWarnings("unused") + boolean invoked = false; + + public void handleMessage(Message message) throws MessagingException { + invoked = true; + } + } + + private static class DummyInterceptor implements MethodInterceptor { + + boolean invoked = false; + + public Object invoke(MethodInvocation invocation) throws Throwable { + invoked = true; + return invocation.proceed(); + } + + @Override + public String toString() { + return super.toString() + "{" + "invoked=" + invoked + '}'; + } + } +}