private RabbitTemplate createTemplate(int concurrentConsumers) {
   RabbitTemplate template = new RabbitTemplate();
   CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
   connectionFactory.setHost("localhost");
   connectionFactory.setChannelCacheSize(concurrentConsumers);
   connectionFactory.setPort(BrokerTestUtils.getPort());
   template.setConnectionFactory(connectionFactory);
   if (messageConverter == null) {
     SimpleMessageConverter messageConverter = new SimpleMessageConverter();
     messageConverter.setCreateMessageIds(true);
     this.messageConverter = messageConverter;
   }
   template.setMessageConverter(messageConverter);
   return template;
 }
  @Test
  public void testStatefulRetryWithNoMessageIds() throws Exception {

    int messageCount = 2;
    int txSize = 1;
    int failFrequency = 1;
    int concurrentConsumers = 1;
    SimpleMessageConverter messageConverter = new SimpleMessageConverter();
    // There will be no key for these messages so they cannot be recovered...
    messageConverter.setCreateMessageIds(false);
    this.messageConverter = messageConverter;
    // Beware of context cache busting if retry policy fails...
    this.retryTemplate = new RetryTemplate();
    this.retryTemplate.setRetryContextCache(new MapRetryContextCache(1));
    // The container should have shutdown, so there are now no active consumers
    exception.expectMessage("expected:<1> but was:<0>");
    doTestStatefulRetry(messageCount, txSize, failFrequency, concurrentConsumers);
  }
  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();
  }