Source:
public void channelReleasedOnTimeout() throws Exception { final CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost"); RabbitTemplate template = createSendAndReceiveRabbitTemplate(connectionFactory); template.setReplyTimeout(1); AtomicReference<Throwable> exception = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(1); ErrorHandler replyErrorHandler = t -> { exception.set(t); latch.countDown(); }; template.setReplyErrorHandler(replyErrorHandler); Object reply = template.convertSendAndReceive(ROUTE, "foo"); assertThat(reply).isNull(); Object container = TestUtils.getPropertyValue(template, "directReplyToContainers", Map.class) .get(template.isUsePublisherConnection() ? connectionFactory.getPublisherConnectionFactory() : connectionFactory); assertThat(TestUtils.getPropertyValue(container, "inUseConsumerChannels", Map.class)).hasSize(0); assertThat(TestUtils.getPropertyValue(container, "errorHandler")).isSameAs(replyErrorHandler); Message replyMessage = new Message("foo".getBytes(), new MessageProperties()); assertThatThrownBy(() -> template.onMessage(replyMessage)) .isInstanceOf(AmqpRejectAndDontRequeueException.class) .hasMessage("No correlation header"); replyMessage.getMessageProperties().setCorrelationId("foo"); assertThatThrownBy(() -> template.onMessage(replyMessage)) .isInstanceOf(AmqpRejectAndDontRequeueException.class) .hasMessage("Reply received after timeout"); ExecutorService executor = Executors.newFixedThreadPool(1); executor.submit(() -> { Message message = template.receive(ROUTE, 10_000); assertNotNull("No message received", message); template.send(message.getMessageProperties().getReplyTo(), replyMessage); return message; }); while (template.receive(ROUTE, 100) != null) { } reply = template.convertSendAndReceive(ROUTE, "foo"); assertThat(reply).isNull(); assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); assertThat(exception.get()).isInstanceOf(ListenerExecutionFailedException.class); assertThat(exception.get().getCause().getMessage()).isEqualTo("Reply received after timeout"); assertThat(((ListenerExecutionFailedException) exception.get()).getFailedMessage().getBody()) .isEqualTo(replyMessage.getBody()); assertThat(TestUtils.getPropertyValue(container, "inUseConsumerChannels", Map.class)).hasSize(0); executor.shutdownNow(); }

Target:
public void channelReleasedOnTimeout() throws Exception { final CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost"); RabbitTemplate template = createSendAndReceiveRabbitTemplate(connectionFactory); template.setReplyTimeout(1); AtomicReference<Throwable> exception = new AtomicReference<>(); CountDownLatch latch = new CountDownLatch(1); ErrorHandler replyErrorHandler = t -> { exception.set(t); latch.countDown(); }; template.setReplyErrorHandler(replyErrorHandler); Object reply = template.convertSendAndReceive(ROUTE, "foo"); assertThat(reply).isNull(); Object container = TestUtils.getPropertyValue(template, "directReplyToContainers", Map.class) .get(template.isUsePublisherConnection() ? connectionFactory.getPublisherConnectionFactory() : connectionFactory); assertThat(TestUtils.getPropertyValue(container, "inUseConsumerChannels", Map.class)).hasSize(0); assertThat(TestUtils.getPropertyValue(container, "errorHandler")).isSameAs(replyErrorHandler); Message replyMessage = new Message("foo".getBytes(), new MessageProperties()); assertThatThrownBy(() -> template.onMessage(replyMessage)) .isInstanceOf(AmqpRejectAndDontRequeueException.class) .hasMessage("No correlation header"); replyMessage.getMessageProperties().setCorrelationId("foo"); assertThatThrownBy(() -> template.onMessage(replyMessage)) .isInstanceOf(AmqpRejectAndDontRequeueException.class) .hasMessage("Reply received after timeout"); ExecutorService executor = Executors.newFixedThreadPool(1); executor.submit(() -> { Message message = template.receive(ROUTE, 10_000); assertNotNull("No message received", message); template.send(message.getMessageProperties().getReplyTo(), replyMessage); return message; }); while (template.receive(ROUTE, 100) != null) { } reply = template.convertSendAndReceive(ROUTE, "foo"); assertThat(reply).isNull(); assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); assertThat(exception.get()).isInstanceOf(ListenerExecutionFailedException.class); assertThat(exception.get().getCause().getMessage()).isEqualTo("Reply received after timeout"); assertThat(((ListenerExecutionFailedException) exception.get()).getFailedMessage().getBody()) .isEqualTo(replyMessage.getBody()); assertThat(TestUtils.getPropertyValue(container, "inUseConsumerChannels", Map.class)).hasSize(0); executor.shutdownNow(); template.stop(); connectionFactory.destroy(); }