AMQP-492: Enhance Timeout Exception (RPC)

JIRA: https://jira.spring.io/browse/AMQP-492

Add method name and arguments to timeout exception in Spring Remoting proxy.
This commit is contained in:
Gary Russell
2015-04-24 12:30:52 +01:00
committed by Artem Bilan
parent fa8cf62440
commit afeb2b64e7
6 changed files with 58 additions and 12 deletions

View File

@@ -13,6 +13,8 @@
package org.springframework.amqp.remoting.client;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
@@ -57,7 +59,11 @@ public class AmqpClientInterceptor extends RemoteAccessor implements MethodInter
}
if (rawResult == null) {
throw new RemoteProxyFailureException("No reply received - perhaps a timeout in the template?", null);
throw new RemoteProxyFailureException("No reply received from '" +
remoteInvocation.getMethodName() +
"' with arguments '" +
Arrays.asList(remoteInvocation.getArguments()) +
"' - perhaps a timeout in the template?", null);
}
else if (!(rawResult instanceof RemoteInvocationResult)) {
throw new RemoteProxyFailureException("Expected a result of type "

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed 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
@@ -15,13 +15,15 @@ package org.springframework.amqp.remoting;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Address;
import org.springframework.amqp.core.AmqpTemplate;
@@ -38,10 +40,13 @@ import org.springframework.amqp.remoting.testservice.TestServiceInterface;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.amqp.support.converter.SimpleMessageConverter;
import org.springframework.remoting.RemoteProxyFailureException;
import org.springframework.remoting.support.RemoteInvocation;
/**
* @author David Bilge
* @author Artem Bilan
* @author Gary Russell
* @since 1.2
*/
public class RemotingTest {
@@ -70,6 +75,11 @@ public class RemotingTest {
AmqpTemplate directForwardingTemplate = new AbstractAmqpTemplate() {
@Override
public Object convertSendAndReceive(Object payload) throws AmqpException {
Object[] arguments = ((RemoteInvocation) payload).getArguments();
if (arguments.length == 1 && arguments[0].equals("timeout")) {
return null;
}
MessageConverter messageConverter = serviceExporter.getMessageConverter();
Address replyTo = new Address("fakeExchangeName", "fakeRoutingKey");
@@ -91,7 +101,17 @@ public class RemotingTest {
@Test
public void testEcho() {
Assert.assertEquals("Echo Test", riggedProxy.simpleStringReturningTestMethod("Test"));
assertEquals("Echo Test", riggedProxy.simpleStringReturningTestMethod("Test"));
}
@Test
public void testSimulatedTimeout() throws Exception {
try {
this.riggedProxy.simulatedTimeoutMethod("timeout");
}
catch (RemoteProxyFailureException e) {
assertThat(e.getMessage(), containsString("'simulatedTimeoutMethod' with arguments '[timeout]'"));
}
}
@Test(expected = RuntimeException.class)
@@ -108,7 +128,7 @@ public class RemotingTest {
@Test
public void testActuallyExceptionReturningMethod() {
SpecialException returnedException = riggedProxy.actuallyExceptionReturningMethod();
Assert.assertNotNull(returnedException);
assertNotNull(returnedException);
}
@Test
@@ -116,7 +136,7 @@ public class RemotingTest {
MessageConverter messageConverter = this.serviceExporter.getMessageConverter();
this.serviceExporter.setMessageConverter(new SimpleMessageConverter() {
private AtomicBoolean invoked = new AtomicBoolean();
private final AtomicBoolean invoked = new AtomicBoolean();
@Override
protected Message createMessage(Object object, MessageProperties messageProperties)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed 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
@@ -18,11 +18,15 @@ import org.springframework.amqp.core.Message;
/**
* @author David Bilge
* @author Gary Russell
* @since 1.2
*/
public class SentSavingTemplate extends AbstractAmqpTemplate {
private Message lastMessage = null;
private String lastExchange = null;
private String lastRoutingKey = null;
@Override
@@ -43,4 +47,5 @@ public class SentSavingTemplate extends AbstractAmqpTemplate {
public String getLastRoutingKey() {
return lastRoutingKey;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed 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
@@ -15,6 +15,7 @@ package org.springframework.amqp.remoting.testservice;
/**
* @author David Bilge
* @author Gary Russell
* @since 1.2
*/
public class TestServiceImpl implements TestServiceInterface {
@@ -47,4 +48,10 @@ public class TestServiceImpl implements TestServiceInterface {
public SpecialException actuallyExceptionReturningMethod() {
return new SpecialException("This exception should not be thrown on the client side but just be returned!");
}
}
@Override
public Object simulatedTimeoutMethod(Object o) {
return null;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed 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
@@ -15,9 +15,11 @@ package org.springframework.amqp.remoting.testservice;
/**
* @author David Bilge
* @author Gary Russell
* @since 1.2
*/
public interface TestServiceInterface {
void simpleTestMethod();
String simpleStringReturningTestMethod(String string);
@@ -29,4 +31,7 @@ public interface TestServiceInterface {
SpecialException notReallyExceptionReturningMethod();
SpecialException actuallyExceptionReturningMethod();
}
Object simulatedTimeoutMethod(Object o);
}

View File

@@ -15,7 +15,9 @@
*/
package org.springframework.amqp.rabbit.remoting;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -25,6 +27,7 @@ import java.util.concurrent.TimeUnit;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.test.BrokerRunning;
import org.springframework.beans.factory.annotation.Autowired;
@@ -75,7 +78,7 @@ public class RemotingTests {
fail("Exception expected");
}
catch (RemoteProxyFailureException e) {
assertTrue("No reply received - perhaps a timeout in the template?".equals(e.getMessage()));
assertThat(e.getMessage(), containsString(" - perhaps a timeout in the template?"));
}
}