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