INT-3007 Add WARN Log When Advice Skipped
Previously, when a MessageHandlerAdvice is applied to something other than a MessageHandler, the advice was silently skipped. Add a WARN log message that warns that the advice is not applied. Add a test case that ensure the log is emitted when the advice is applied to a Poller.
This commit is contained in:
@@ -21,6 +21,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.aop.ProxyMethodInvocation;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.context.IntegrationObjectSupport;
|
||||
@@ -50,6 +51,11 @@ public abstract class AbstractRequestHandlerAdvice extends IntegrationObjectSupp
|
||||
&& (arguments.length == 1 && arguments[0] instanceof Message);
|
||||
|
||||
if (!isMessageMethod) {
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("This advice " + this.getClass().getName() +
|
||||
" can only be used for MessageHandlers; an attempt to advise method '" + method.getName() +
|
||||
"' in '" + method.getDeclaringClass().getName() + "' is ignored");
|
||||
}
|
||||
return invocation.proceed();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.integration.handler.advice;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
@@ -23,37 +24,52 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.core.PollableChannel;
|
||||
import org.springframework.integration.endpoint.PollingConsumer;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.MessageHandlingExpressionEvaluatingAdviceException;
|
||||
import org.springframework.integration.message.AdviceMessage;
|
||||
import org.springframework.integration.message.ErrorMessage;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.util.ErrorHandlingTaskExecutor;
|
||||
import org.springframework.retry.RecoveryCallback;
|
||||
import org.springframework.retry.RetryContext;
|
||||
import org.springframework.retry.RetryState;
|
||||
import org.springframework.retry.policy.SimpleRetryPolicy;
|
||||
import org.springframework.retry.support.DefaultRetryState;
|
||||
import org.springframework.retry.support.RetryTemplate;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
@@ -787,6 +803,55 @@ public class AdvisedMessageHandlerTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInappropriateAdvice() throws Exception {
|
||||
final AtomicBoolean called = new AtomicBoolean(false);
|
||||
Advice advice = new AbstractRequestHandlerAdvice() {
|
||||
@Override
|
||||
protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
|
||||
called.set(true);
|
||||
return callback.execute();
|
||||
}
|
||||
};
|
||||
PollableChannel inputChannel = new QueueChannel();
|
||||
PollingConsumer consumer = new PollingConsumer(inputChannel, new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
}
|
||||
});
|
||||
consumer.setAdviceChain(Collections.singletonList(advice));
|
||||
consumer.setTaskExecutor(new ErrorHandlingTaskExecutor(
|
||||
Executors.newSingleThreadExecutor(),
|
||||
new ErrorHandler() {
|
||||
@Override
|
||||
public void handleError(Throwable t) {
|
||||
}
|
||||
}));
|
||||
consumer.afterPropertiesSet();
|
||||
|
||||
Callable<?> pollingTask = TestUtils.getPropertyValue(consumer, "poller.pollingTask", Callable.class);
|
||||
assertTrue(AopUtils.isAopProxy(pollingTask));
|
||||
Log logger = TestUtils.getPropertyValue(advice, "logger", Log.class);
|
||||
logger = spy(logger);
|
||||
when(logger.isWarnEnabled()).thenReturn(Boolean.TRUE);
|
||||
final AtomicReference<String> logMessage = new AtomicReference<String>();
|
||||
doAnswer(new Answer<Object>() {
|
||||
@Override
|
||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||
logMessage.set((String) invocation.getArguments()[0]);
|
||||
return null;
|
||||
}
|
||||
}).when(logger).warn(Mockito.anyString());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(advice);
|
||||
accessor.setPropertyValue("logger", logger);
|
||||
|
||||
pollingTask.call();
|
||||
assertFalse(called.get());
|
||||
assertNotNull(logMessage.get());
|
||||
assertTrue(logMessage.get().endsWith("can only be used for MessageHandlers; " +
|
||||
"an attempt to advise method 'call' in 'java.util.concurrent.Callable' is ignored"));
|
||||
}
|
||||
|
||||
private interface Bar {
|
||||
Object handleRequestMessage(Message<?> message) throws Throwable;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user