public void sendMessage(String... varStrings) {
    String msg = varStrings[0];
    String exchangeName = varStrings[1];
    String qName = varStrings[2];
    String rabbitIp = varStrings[3];

    logger.debug("RabbitMQ Properties Start...");
    logger.debug("Message - " + msg);
    logger.debug("Exchange Name - " + exchangeName);
    logger.debug("QueueName - " + qName);
    logger.debug("IP Address - " + rabbitIp);
    logger.debug("RabbitMQ Properties End...");

    try {
      CachingConnectionFactory factory = new CachingConnectionFactory();
      factory.setAddresses(rabbitIp);
      org.springframework.amqp.rabbit.connection.Connection connection = factory.createConnection();
      Channel channel = connection.createChannel(false);
      channel.basicPublish(exchangeName, qName, null, msg.getBytes());
      channel.close();
      connection.close();
      logger.debug("Message Sent...");

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 @Bean
 public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config)
     throws Exception {
   RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
   if (config.getHost() != null) {
     factory.setHost(config.getHost());
     factory.setPort(config.getPort());
   }
   if (config.getUsername() != null) {
     factory.setUsername(config.getUsername());
   }
   if (config.getPassword() != null) {
     factory.setPassword(config.getPassword());
   }
   if (config.getVirtualHost() != null) {
     factory.setVirtualHost(config.getVirtualHost());
   }
   if (config.getRequestedHeartbeat() != null) {
     factory.setRequestedHeartbeat(config.getRequestedHeartbeat());
   }
   RabbitProperties.Ssl ssl = config.getSsl();
   if (ssl.isEnabled()) {
     factory.setUseSSL(true);
     factory.setKeyStore(ssl.getKeyStore());
     factory.setKeyStorePassphrase(ssl.getKeyStorePassword());
     factory.setTrustStore(ssl.getTrustStore());
     factory.setTrustStorePassphrase(ssl.getTrustStorePassword());
   }
   factory.afterPropertiesSet();
   CachingConnectionFactory connectionFactory =
       new CachingConnectionFactory(factory.getObject());
   connectionFactory.setAddresses(config.getAddresses());
   return connectionFactory;
 }
 private static ConnectionFactory getConnectionFactory(
     String host, String username, String password) {
   CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host);
   connectionFactory.setPassword(password);
   connectionFactory.setUsername(username);
   return connectionFactory;
 }
 @Before
 public void createConnectionFactory() {
   CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
   connectionFactory.setChannelCacheSize(concurrentConsumers);
   connectionFactory.setPort(BrokerTestUtils.getPort());
   template.setConnectionFactory(connectionFactory);
 }
 @Test
 public void testConnectionFactoryDefaultVirtualHost() {
   load(TestConfiguration.class, "spring.rabbitmq.virtual_host:/");
   CachingConnectionFactory connectionFactory =
       this.context.getBean(CachingConnectionFactory.class);
   assertThat(connectionFactory.getVirtualHost()).isEqualTo("/");
 }
  @Test
  public void testPublisherConfirmNotReceived() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);

    when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection);
    when(mockConnection.isOpen()).thenReturn(true);
    doReturn(new PublisherCallbackChannelImpl(mockChannel)).when(mockConnection).createChannel();

    CachingConnectionFactory ccf = new CachingConnectionFactory(mockConnectionFactory);
    ccf.setPublisherConfirms(true);
    final RabbitTemplate template = new RabbitTemplate(ccf);

    final AtomicBoolean confirmed = new AtomicBoolean();
    template.setConfirmCallback(
        new ConfirmCallback() {

          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            confirmed.set(true);
          }
        });
    template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("abc"));
    Thread.sleep(5);
    Collection<CorrelationData> unconfirmed = template.getUnconfirmed(-1);
    assertEquals(1, unconfirmed.size());
    assertEquals("abc", unconfirmed.iterator().next().getId());
    assertFalse(confirmed.get());
  }
 @Before
 public void declareQueue() {
   CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
   connectionFactory.setChannelCacheSize(concurrentConsumers);
   // connectionFactory.setPort(5673);
   template.setConnectionFactory(connectionFactory);
 }
  public void receiveMessage(String qName) {
    try {
      CachingConnectionFactory factory = new CachingConnectionFactory();
      factory.setAddresses("10.30.135.103:5672,10.30.135.101:5672");
      org.springframework.amqp.rabbit.connection.Connection connection = factory.createConnection();
      Channel channel = connection.createChannel(false);

      // channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
      // ring queueName = channel.queueDeclare().getQueue();
      // channel.queueBind(queueName, EXCHANGE_NAME, "");

      System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

      QueueingConsumer consumer = new QueueingConsumer(channel);
      channel.basicConsume(qName, true, consumer);

      while (true) {
        QueueingConsumer.Delivery delivery = consumer.nextDelivery();
        String message = new String(delivery.getBody());

        System.out.println(" [x] Received '" + message + "'");
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 @Before
 public void declareQueue() {
   CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
   connectionFactory.setHost("localhost");
   connectionFactory.setChannelCacheSize(concurrentConsumers);
   connectionFactory.setPort(BrokerTestUtils.getPort());
   template.setConnectionFactory(connectionFactory);
 }
 @Bean
 public ConnectionFactory connectionFactory() {
   CachingConnectionFactory connectionFactory = new CachingConnectionFactory("rabbitmq");
   // CachingConnectionFactory connectionFactory = new CachingConnectionFactory("192.168.99.104");
   connectionFactory.setUsername("guest");
   connectionFactory.setPassword("guest");
   return connectionFactory;
 }
  // AMQP-506 ConcurrentModificationException
  @Test
  public void testPublisherConfirmGetUnconfirmedConcurrency() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);
    when(mockChannel.isOpen()).thenReturn(true);
    final AtomicLong seq = new AtomicLong();
    doAnswer(
            new Answer<Long>() {

              @Override
              public Long answer(InvocationOnMock invocation) throws Throwable {
                return seq.incrementAndGet();
              }
            })
        .when(mockChannel)
        .getNextPublishSeqNo();

    when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection);
    when(mockConnection.isOpen()).thenReturn(true);
    doReturn(mockChannel).when(mockConnection).createChannel();

    CachingConnectionFactory ccf = new CachingConnectionFactory(mockConnectionFactory);
    ccf.setPublisherConfirms(true);
    final RabbitTemplate template = new RabbitTemplate(ccf);

    final AtomicBoolean confirmed = new AtomicBoolean();
    template.setConfirmCallback(
        new ConfirmCallback() {

          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            confirmed.set(true);
          }
        });
    ExecutorService exec = Executors.newSingleThreadExecutor();
    final AtomicBoolean sentAll = new AtomicBoolean();
    exec.execute(
        new Runnable() {

          @Override
          public void run() {
            for (int i = 0; i < 10000; i++) {
              template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("abc"));
            }
            sentAll.set(true);
          }
        });
    Collection<CorrelationData> unconfirmed = template.getUnconfirmed(-1);
    long t1 = System.currentTimeMillis();
    while (!sentAll.get() && System.currentTimeMillis() < t1 + 20000) {
      unconfirmed = template.getUnconfirmed(-1);
    }
    assertTrue(sentAll.get());
    assertFalse(confirmed.get());
  }
 @Test
 public void testConnectionFactoryBackOff() {
   load(TestConfiguration2.class);
   RabbitTemplate rabbitTemplate = this.context.getBean(RabbitTemplate.class);
   CachingConnectionFactory connectionFactory =
       this.context.getBean(CachingConnectionFactory.class);
   assertThat(connectionFactory).isEqualTo(rabbitTemplate.getConnectionFactory());
   assertThat(connectionFactory.getHost()).isEqualTo("otherserver");
   assertThat(connectionFactory.getPort()).isEqualTo(8001);
 }
 @Test
 public void testConnectionFactoryWithOverrides() {
   load(
       TestConfiguration.class,
       "spring.rabbitmq.host:remote-server",
       "spring.rabbitmq.port:9000",
       "spring.rabbitmq.username:alice",
       "spring.rabbitmq.password:secret",
       "spring.rabbitmq.virtual_host:/vhost");
   CachingConnectionFactory connectionFactory =
       this.context.getBean(CachingConnectionFactory.class);
   assertThat(connectionFactory.getHost()).isEqualTo("remote-server");
   assertThat(connectionFactory.getPort()).isEqualTo(9000);
   assertThat(connectionFactory.getVirtualHost()).isEqualTo("/vhost");
 }
  @After
  public void cleanUp() {
    if (connectionFactory != null) {
      connectionFactory.destroy();
    }

    if (connectionFactoryWithConfirmsEnabled != null) {
      connectionFactoryWithConfirmsEnabled.destroy();
    }

    if (connectionFactoryWithReturnsEnabled != null) {
      connectionFactoryWithReturnsEnabled.destroy();
    }
    this.brokerIsRunning.removeTestQueues();
  }
 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;
 }
  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 testPublisherConfirmMultiple() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);

    when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection);
    when(mockConnection.isOpen()).thenReturn(true);
    PublisherCallbackChannelImpl callbackChannel = new PublisherCallbackChannelImpl(mockChannel);
    when(mockConnection.createChannel()).thenReturn(callbackChannel);

    final AtomicInteger count = new AtomicInteger();
    doAnswer(
            new Answer<Object>() {
              @Override
              public Object answer(InvocationOnMock invocation) throws Throwable {
                return count.incrementAndGet();
              }
            })
        .when(mockChannel)
        .getNextPublishSeqNo();

    CachingConnectionFactory ccf = new CachingConnectionFactory(mockConnectionFactory);
    ccf.setPublisherConfirms(true);
    final RabbitTemplate template = new RabbitTemplate(ccf);

    final CountDownLatch latch = new CountDownLatch(2);
    template.setConfirmCallback(
        new ConfirmCallback() {

          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            if (ack) {
              latch.countDown();
            }
          }
        });
    template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("abc"));
    template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("def"));
    callbackChannel.handleAck(2, true);
    assertTrue(latch.await(1000, TimeUnit.MILLISECONDS));
    Collection<CorrelationData> unconfirmed = template.getUnconfirmed(-1);
    assertNull(unconfirmed);
  }
  @Bean
  public CachingConnectionFactory rabbitConnectionFactory() {
    log.info("AMQP URL: {}", isBlank(amqpConnectionUri) ? "localhost:5672" : amqpConnectionUri);

    RabbitConnectionFactoryConfig config = uriToConnectionConfig(amqpConnectionUri);
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory(config.getHost());
    connectionFactory.setPort(config.getPort());

    if (config.getUsername() != null) {
      connectionFactory.setUsername(config.getUsername());
    }
    if (config.getPassword() != null) {
      connectionFactory.setPassword(config.getPassword());
    }
    if (config.getVirtualHost() != null) {
      connectionFactory.setVirtualHost(StringUtils.remove(config.getVirtualHost(), '/'));
    }

    return connectionFactory;
  }
 @Test
 public void testDefaultRabbitConfiguration() {
   load(TestConfiguration.class);
   RabbitTemplate rabbitTemplate = this.context.getBean(RabbitTemplate.class);
   RabbitMessagingTemplate messagingTemplate = this.context.getBean(RabbitMessagingTemplate.class);
   CachingConnectionFactory connectionFactory =
       this.context.getBean(CachingConnectionFactory.class);
   DirectFieldAccessor dfa = new DirectFieldAccessor(connectionFactory);
   RabbitAdmin amqpAdmin = this.context.getBean(RabbitAdmin.class);
   assertThat(rabbitTemplate.getConnectionFactory()).isEqualTo(connectionFactory);
   assertThat(getMandatory(rabbitTemplate)).isFalse();
   assertThat(messagingTemplate.getRabbitTemplate()).isEqualTo(rabbitTemplate);
   assertThat(amqpAdmin).isNotNull();
   assertThat(connectionFactory.getHost()).isEqualTo("localhost");
   assertThat(dfa.getPropertyValue("publisherConfirms")).isEqualTo(false);
   assertThat(dfa.getPropertyValue("publisherReturns")).isEqualTo(false);
   assertThat(this.context.containsBean("rabbitListenerContainerFactory"))
       .as("Listener container factory should be created by default")
       .isTrue();
 }
  /**
   * Avoid the possibility of not configuring the CachingConnectionFactory in sync with the number
   * of concurrent consumers.
   */
  @Override
  protected void validateConfiguration() {

    super.validateConfiguration();

    Assert.state(
        !(getAcknowledgeMode().isAutoAck() && transactionManager != null),
        "The acknowledgeMode is NONE (autoack in Rabbit terms) which is not consistent with having an "
            + "external transaction manager. Either use a different AcknowledgeMode or make sure the transactionManager is null.");

    if (this.getConnectionFactory() instanceof CachingConnectionFactory) {
      CachingConnectionFactory cf = (CachingConnectionFactory) getConnectionFactory();
      if (cf.getChannelCacheSize() < this.concurrentConsumers) {
        cf.setChannelCacheSize(this.concurrentConsumers);
        logger.warn(
            "CachingConnectionFactory's channelCacheSize can not be less than the number of concurrentConsumers so it was reset to match: "
                + this.concurrentConsumers);
      }
    }
  }
  /**
   * Constructor
   *
   * @param host Host name
   * @param port Host connection port
   * @param username Connection user name
   * @param password Connection password
   * @param virtualHost RabbitMQ virtual host
   * @param exchangeName RabbitMQ exchange name
   * @param queueName Queue name
   */
  public RabbitMQTopicQueueProducer(
      String host,
      int port,
      String username,
      String password,
      String virtualHost,
      String exchangeName,
      String queueName) {
    super();

    CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port);
    connectionFactory.setUsername(username);
    connectionFactory.setPassword(password);
    connectionFactory.setVirtualHost(virtualHost);
    RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
    rabbitTemplate.setExchange(exchangeName);
    rabbitTemplate.setQueue(queueName);

    this.setConnectionFactory(connectionFactory);
    this.setRabbitTemplate(rabbitTemplate);
  }
  public Map<String, String> runDiagnostics() {
    final Map<String, String> diagnostics = new TreeMap<String, String>();
    final CachingConnectionFactory serverConnectionFactory = new CachingConnectionFactory(host);
    serverConnectionFactory.setVirtualHost(virtualHost);
    serverConnectionFactory.setUsername("pat");
    serverConnectionFactory.setPassword("p0stm4n");

    testConfig(diagnostics, "Server", serverConnectionFactory);

    final CachingConnectionFactory clientConnectionFactory = new CachingConnectionFactory(host);
    clientConnectionFactory.setVirtualHost(virtualHost);
    clientConnectionFactory.setUsername("flash");
    clientConnectionFactory.setPassword("readonly");
    testConfig(diagnostics, "Client", clientConnectionFactory);

    return diagnostics;
  }
  private void testConfig(
      final Map<String, String> diagnostics,
      final String configName,
      final CachingConnectionFactory factory) {
    final String connectKey = String.format(CAN_CONNECT, configName);
    final RabbitAdmin admin;
    try {
      factory.createConnection();
      admin = new RabbitAdmin(factory);
      diagnostics.put(connectKey, valueOf(true));
    } catch (Exception e) {
      diagnostics.put(connectKey, valueOf(false));
      return;
    }

    final boolean canAccessExchange = tryDeclaringExchange(admin);
    diagnostics.put(
        String.format(CAN_ACCESS_EXCHANGE, configName), String.valueOf(canAccessExchange));

    final boolean canDeclareQueue = tryUsingQueue(admin);
    diagnostics.put(String.format(CAN_USE_QUEUES, configName), String.valueOf(canDeclareQueue));
  }
  /**
   * AMQP-262 Sets up a situation where we are processing 'multi' acks at the same time as adding a
   * new pending ack to the map. Test verifies we don't get a {@link
   * ConcurrentModificationException}.
   */
  @SuppressWarnings({"rawtypes", "unchecked", "deprecation"})
  @Test
  public void testConcurrentConfirms() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);
    when(mockChannel.getNextPublishSeqNo()).thenReturn(1L, 2L, 3L, 4L);

    when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection);
    when(mockConnection.isOpen()).thenReturn(true);
    final PublisherCallbackChannelImpl channel = new PublisherCallbackChannelImpl(mockChannel);
    when(mockConnection.createChannel()).thenReturn(channel);

    CachingConnectionFactory ccf = new CachingConnectionFactory(mockConnectionFactory);
    ccf.setPublisherConfirms(true);
    ccf.setChannelCacheSize(3);
    final RabbitTemplate template = new RabbitTemplate(ccf);

    final CountDownLatch first2SentOnThread1Latch = new CountDownLatch(1);
    final CountDownLatch delayAckProcessingLatch = new CountDownLatch(1);
    final CountDownLatch startedProcessingMultiAcksLatch = new CountDownLatch(1);
    final CountDownLatch waitForAll3AcksLatch = new CountDownLatch(3);
    final CountDownLatch allSentLatch = new CountDownLatch(1);
    final AtomicInteger acks = new AtomicInteger();
    template.setConfirmCallback(
        new ConfirmCallback() {

          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            try {
              startedProcessingMultiAcksLatch.countDown();
              // delay processing here; ensures thread 2 put would be concurrent
              delayAckProcessingLatch.await(2, TimeUnit.SECONDS);
              // only delay first time through
              delayAckProcessingLatch.countDown();
              waitForAll3AcksLatch.countDown();
              acks.incrementAndGet();
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        });
    Executors.newSingleThreadExecutor()
        .execute(
            new Runnable() {
              @Override
              public void run() {
                template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("abc"));
                template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("def"));
                first2SentOnThread1Latch.countDown();
              }
            });
    Executors.newSingleThreadExecutor()
        .execute(
            new Runnable() {
              @Override
              public void run() {
                try {
                  startedProcessingMultiAcksLatch.await();
                  template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("ghi"));
                  allSentLatch.countDown();
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }
            });
    assertTrue(first2SentOnThread1Latch.await(10, TimeUnit.SECONDS));
    // there should be no concurrent execution exception here
    channel.handleAck(2, true);
    assertTrue(allSentLatch.await(10, TimeUnit.SECONDS));
    channel.handleAck(3, false);
    assertTrue(waitForAll3AcksLatch.await(10, TimeUnit.SECONDS));
    assertEquals(3, acks.get());

    // 3.3.1 client
    channel.basicConsume("foo", false, (Map) null, null);
    verify(mockChannel).basicConsume("foo", false, (Map) null, null);

    channel.basicQos(3, false);
    verify(mockChannel).basicQos(3, false);

    doReturn(true).when(mockChannel).flowBlocked();
    assertTrue(channel.flowBlocked());

    try {
      channel.flow(true);
      fail("Expected exception");
    } catch (UnsupportedOperationException e) {
    }

    try {
      channel.getFlow();
      fail("Expected exception");
    } catch (UnsupportedOperationException e) {
    }

    // 3.2.4 client
    /*
    		try {
    			channel.basicConsume("foo", false, (Map) null, (Consumer) null);
    			fail("Expected exception");
    		}
    		catch (UnsupportedOperationException e) {}

    		try {
    			channel.basicQos(3, false);
    			fail("Expected exception");
    		}
    		catch (UnsupportedOperationException e) {}

    		try {
    			channel.flowBlocked();
    			fail("Expected exception");
    		}
    		catch (UnsupportedOperationException e) {}

    		channel.flow(true);
    		verify(mockChannel).flow(true);

    		channel.getFlow();
    		verify(mockChannel).getFlow();
    */
  }
  /**
   * Tests that piggy-backed confirms (multiple=true) are distributed to the proper template.
   *
   * @throws Exception
   */
  @Test
  public void testPublisherConfirmMultipleWithTwoListeners() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel = mock(Channel.class);

    when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection);
    when(mockConnection.isOpen()).thenReturn(true);
    PublisherCallbackChannelImpl callbackChannel = new PublisherCallbackChannelImpl(mockChannel);
    when(mockConnection.createChannel()).thenReturn(callbackChannel);

    final AtomicInteger count = new AtomicInteger();
    doAnswer(
            new Answer<Object>() {
              @Override
              public Object answer(InvocationOnMock invocation) throws Throwable {
                return count.incrementAndGet();
              }
            })
        .when(mockChannel)
        .getNextPublishSeqNo();

    CachingConnectionFactory ccf = new CachingConnectionFactory(mockConnectionFactory);
    ccf.setPublisherConfirms(true);
    final RabbitTemplate template1 = new RabbitTemplate(ccf);

    final Set<String> confirms = new HashSet<String>();
    final CountDownLatch latch1 = new CountDownLatch(1);
    template1.setConfirmCallback(
        new ConfirmCallback() {

          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            if (ack) {
              confirms.add(correlationData.getId() + "1");
              latch1.countDown();
            }
          }
        });
    final RabbitTemplate template2 = new RabbitTemplate(ccf);

    final CountDownLatch latch2 = new CountDownLatch(1);
    template2.setConfirmCallback(
        new ConfirmCallback() {

          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            if (ack) {
              confirms.add(correlationData.getId() + "2");
              latch2.countDown();
            }
          }
        });
    template1.convertAndSend(ROUTE, (Object) "message", new CorrelationData("abc"));
    template2.convertAndSend(ROUTE, (Object) "message", new CorrelationData("def"));
    template2.convertAndSend(ROUTE, (Object) "message", new CorrelationData("ghi"));
    callbackChannel.handleAck(3, true);
    assertTrue(latch1.await(1000, TimeUnit.MILLISECONDS));
    assertTrue(latch2.await(1000, TimeUnit.MILLISECONDS));
    Collection<CorrelationData> unconfirmed1 = template1.getUnconfirmed(-1);
    assertNull(unconfirmed1);
    Collection<CorrelationData> unconfirmed2 = template2.getUnconfirmed(-1);
    assertNull(unconfirmed2);
    assertTrue(confirms.contains("abc1"));
    assertTrue(confirms.contains("def2"));
    assertTrue(confirms.contains("ghi2"));
    assertEquals(3, confirms.size());
  }
  @Test
  public void testPublisherConfirmNotReceivedMultiThreads() throws Exception {
    ConnectionFactory mockConnectionFactory = mock(ConnectionFactory.class);
    Connection mockConnection = mock(Connection.class);
    Channel mockChannel1 = mock(Channel.class);
    Channel mockChannel2 = mock(Channel.class);
    when(mockChannel1.isOpen()).thenReturn(true);
    when(mockChannel2.isOpen()).thenReturn(true);
    when(mockChannel1.getNextPublishSeqNo()).thenReturn(1L, 2L, 3L, 4L);
    when(mockChannel2.getNextPublishSeqNo()).thenReturn(1L, 2L, 3L, 4L);

    when(mockConnectionFactory.newConnection((ExecutorService) null)).thenReturn(mockConnection);
    when(mockConnection.isOpen()).thenReturn(true);
    PublisherCallbackChannelImpl channel1 = new PublisherCallbackChannelImpl(mockChannel1);
    PublisherCallbackChannelImpl channel2 = new PublisherCallbackChannelImpl(mockChannel2);
    when(mockConnection.createChannel()).thenReturn(channel1).thenReturn(channel2);

    CachingConnectionFactory ccf = new CachingConnectionFactory(mockConnectionFactory);
    ccf.setPublisherConfirms(true);
    ccf.setChannelCacheSize(3);
    final RabbitTemplate template = new RabbitTemplate(ccf);

    final AtomicBoolean confirmed = new AtomicBoolean();
    template.setConfirmCallback(
        new ConfirmCallback() {

          @Override
          public void confirm(CorrelationData correlationData, boolean ack, String cause) {
            confirmed.set(true);
          }
        });

    // Hold up the first thread so we get two channels
    final CountDownLatch threadLatch = new CountDownLatch(1);
    final CountDownLatch threadSentLatch = new CountDownLatch(1);
    // Thread 1
    ExecutorService exec = Executors.newSingleThreadExecutor();
    exec.execute(
        new Runnable() {

          @Override
          public void run() {
            template.execute(
                new ChannelCallback<Object>() {
                  @Override
                  public Object doInRabbit(Channel channel) throws Exception {
                    try {
                      threadLatch.await(10, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                      Thread.currentThread().interrupt();
                    }
                    template.doSend(
                        channel,
                        "",
                        ROUTE,
                        new SimpleMessageConverter().toMessage("message", new MessageProperties()),
                        false,
                        new CorrelationData("def"));
                    threadSentLatch.countDown();
                    return null;
                  }
                });
          }
        });

    // Thread 2
    template.convertAndSend(ROUTE, (Object) "message", new CorrelationData("abc")); // channel y
    threadLatch.countDown();
    assertTrue(threadSentLatch.await(5, TimeUnit.SECONDS));
    Collection<CorrelationData> unconfirmed = template.getUnconfirmed(-1);
    assertEquals(2, unconfirmed.size());
    Set<String> ids = new HashSet<String>();
    Iterator<CorrelationData> iterator = unconfirmed.iterator();
    ids.add(iterator.next().getId());
    ids.add(iterator.next().getId());
    assertTrue(ids.remove("abc"));
    assertTrue(ids.remove("def"));
    assertFalse(confirmed.get());
    DirectFieldAccessor dfa = new DirectFieldAccessor(template);
    Map<?, ?> pendingConfirms = (Map<?, ?>) dfa.getPropertyValue("pendingConfirms");
    assertThat(pendingConfirms.size(), greaterThan(0)); // might use 2 or only 1 channel
    exec.shutdown();
    assertTrue(exec.awaitTermination(10, TimeUnit.SECONDS));
    ccf.destroy();
    assertEquals(0, pendingConfirms.size());
  }
 @Before
 public void create() {
   connectionFactory = new CachingConnectionFactory();
   connectionFactory.setHost("localhost");
   connectionFactory.setChannelCacheSize(10);
   connectionFactory.setPort(BrokerTestUtils.getPort());
   connectionFactoryWithConfirmsEnabled = new CachingConnectionFactory();
   connectionFactoryWithConfirmsEnabled.setHost("localhost");
   // When using publisher confirms, the cache size needs to be large enough
   // otherwise channels can be closed before confirms are received.
   connectionFactoryWithConfirmsEnabled.setChannelCacheSize(100);
   connectionFactoryWithConfirmsEnabled.setPort(BrokerTestUtils.getPort());
   connectionFactoryWithConfirmsEnabled.setPublisherConfirms(true);
   templateWithConfirmsEnabled = new RabbitTemplate(connectionFactoryWithConfirmsEnabled);
   connectionFactoryWithReturnsEnabled = new CachingConnectionFactory();
   connectionFactoryWithReturnsEnabled.setHost("localhost");
   connectionFactoryWithReturnsEnabled.setChannelCacheSize(1);
   connectionFactoryWithReturnsEnabled.setPort(BrokerTestUtils.getPort());
   connectionFactoryWithReturnsEnabled.setPublisherReturns(true);
   templateWithReturnsEnabled = new RabbitTemplate(connectionFactoryWithReturnsEnabled);
 }