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); }