private void doListenerWithExceptionTest(CountDownLatch latch, Object listener) throws Exception { container = createContainer(listener); if (acknowledgeMode.isTransactionAllowed()) { // Should only need one message if it is going to fail for (int i = 0; i < concurrentConsumers; i++) { template.convertAndSend(queue.getName(), i + "foo"); } } else { for (int i = 0; i < messageCount; i++) { template.convertAndSend(queue.getName(), i + "foo"); } } try { boolean waited = latch.await(10 + Math.max(1, messageCount / 10), TimeUnit.SECONDS); assertTrue("Timed out waiting for message", waited); } finally { // Wait for broker communication to finish before trying to stop // container Thread.sleep(300L); container.shutdown(); Thread.sleep(300L); } if (acknowledgeMode.isTransactionAllowed()) { assertNotNull(template.receiveAndConvert(queue.getName())); } else { assertNull(template.receiveAndConvert(queue.getName())); } }
@After public void clear() throws Exception { // Wait for broker communication to finish before trying to stop container Thread.sleep(300L); logger.debug("Shutting down at end of test"); if (container != null) { container.shutdown(); } ((DisposableBean) template.getConnectionFactory()).destroy(); }
private void doTest(int concurrentConsumers, ContainerConfigurer configurer) { int messageCount = 10; RabbitTemplate template = new RabbitTemplate(); CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); connectionFactory.setHost("localhost"); connectionFactory.setChannelCacheSize(concurrentConsumers); connectionFactory.setPort(BrokerTestUtils.getPort()); template.setConnectionFactory(connectionFactory); SimpleMessageConverter messageConverter = new SimpleMessageConverter(); messageConverter.setCreateMessageIds(true); template.setMessageConverter(messageConverter); for (int i = 0; i < messageCount; i++) { template.convertAndSend(queue1.getName(), new Integer(i)); template.convertAndSend(queue2.getName(), new Integer(i)); } final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory); final CountDownLatch latch = new CountDownLatch(messageCount * 2); PojoListener listener = new PojoListener(latch); container.setMessageListener(new MessageListenerAdapter(listener)); container.setAcknowledgeMode(AcknowledgeMode.AUTO); container.setChannelTransacted(true); container.setConcurrentConsumers(concurrentConsumers); configurer.configure(container); container.afterPropertiesSet(); container.start(); try { int timeout = Math.min(1 + messageCount / concurrentConsumers, 30); boolean waited = latch.await(timeout, TimeUnit.SECONDS); logger.info("All messages recovered: " + waited); assertEquals(concurrentConsumers, container.getActiveConsumerCount()); assertTrue("Timed out waiting for messages", waited); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new IllegalStateException("unexpected interruption"); } finally { container.shutdown(); assertEquals(0, container.getActiveConsumerCount()); } assertNull(template.receiveAndConvert(queue1.getName())); assertNull(template.receiveAndConvert(queue2.getName())); connectionFactory.destroy(); }
@Test public void testListenerSunnyDay() throws Exception { CountDownLatch latch = new CountDownLatch(messageCount); for (int i = 0; i < messageCount; i++) { template.convertAndSend(queue.getName(), i + "foo"); } SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(template.getConnectionFactory()); container.setMessageListener(new MessageListenerAdapter(new PojoListener(latch))); container.setChannelTransacted(transactional); container.setConcurrentConsumers(concurrentConsumers); container.setQueueName(queue.getName()); container.afterPropertiesSet(); container.start(); try { boolean waited = latch.await(50, TimeUnit.MILLISECONDS); assertFalse("Expected time out waiting for message", waited); container.stop(); Thread.sleep(500L); container.start(); if (transactional) { waited = latch.await(5, TimeUnit.SECONDS); assertTrue("Timed out waiting for message", waited); } else { waited = latch.await(500, TimeUnit.MILLISECONDS); // If non-transactional we half expect to lose messages assertFalse("Expected time out waiting for message", waited); } } finally { // Wait for broker communication to finish before trying to stop // container Thread.sleep(300L); container.shutdown(); } assertNull(template.receiveAndConvert(queue.getName())); }
private void doTestRetry( int messageCount, int txSize, int failFrequency, int concurrentConsumers, boolean stateful) throws Exception { int failedMessageCount = messageCount / failFrequency + (messageCount % failFrequency == 0 ? 0 : 1); RabbitTemplate template = createTemplate(concurrentConsumers); for (int i = 0; i < messageCount; i++) { template.convertAndSend(queue.getName(), i); } final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(template.getConnectionFactory()); PojoListener listener = new PojoListener(failFrequency); container.setMessageListener(new MessageListenerAdapter(listener)); container.setAcknowledgeMode(AcknowledgeMode.AUTO); container.setChannelTransacted(true); container.setTxSize(txSize); container.setConcurrentConsumers(concurrentConsumers); final CountDownLatch latch = new CountDownLatch(failedMessageCount); container.setAdviceChain(new Advice[] {createRetryInterceptor(latch, stateful)}); container.setQueueNames(queue.getName()); container.afterPropertiesSet(); container.start(); try { int timeout = Math.min(1 + 2 * messageCount / concurrentConsumers, 30); final int count = messageCount; logger.debug("Waiting for messages with timeout = " + timeout + " (s)"); Executors.newSingleThreadExecutor() .execute( () -> { while (container.getActiveConsumerCount() > 0) { try { Thread.sleep(100L); } catch (InterruptedException e) { latch.countDown(); Thread.currentThread().interrupt(); return; } } for (int i = 0; i < count; i++) { latch.countDown(); } }); boolean waited = latch.await(timeout, TimeUnit.SECONDS); logger.info("All messages recovered: " + waited); assertEquals(concurrentConsumers, container.getActiveConsumerCount()); assertTrue("Timed out waiting for messages", waited); // Retried each failure 3 times (default retry policy)... assertEquals(3 * failedMessageCount, listener.getCount()); // All failed messages recovered assertEquals(null, template.receiveAndConvert(queue.getName())); } finally { container.shutdown(); ((DisposableBean) template.getConnectionFactory()).destroy(); assertEquals(0, container.getActiveConsumerCount()); } }