@SuppressWarnings("unchecked") private void waitForNewConsumer(PublishSubscribeAmqpChannel channel, BlockingQueueConsumer consumer) throws Exception { final Object consumersMonitor = TestUtils.getPropertyValue(channel, "container.consumersMonitor"); int n = 0; while (n++ < 100) { Set<BlockingQueueConsumer> consumers = TestUtils.getPropertyValue(channel, "container.consumers", Set.class); synchronized (consumersMonitor) { if (!consumers.isEmpty()) { BlockingQueueConsumer newConsumer = consumers.iterator().next(); if (newConsumer != consumer && newConsumer.getConsumerTags().size() > 0) { break; } } } Thread.sleep(100); } assertTrue("Failed to restart consumer", n < 100); }
protected BlockingQueueConsumer createBlockingQueueConsumer() { BlockingQueueConsumer consumer; String[] queues = getQueueNames(); // There's no point prefetching less than the tx size, otherwise the consumer will stall because the broker // didn't get an ack for delivered messages int actualPrefetchCount = getPrefetchCount() > this.txSize ? getPrefetchCount() : this.txSize; consumer = new BlockingQueueConsumer(getConnectionFactory(), getMessagePropertiesConverter(), this.cancellationLock, getAcknowledgeMode(), isChannelTransacted(), actualPrefetchCount, isDefaultRequeueRejected(), getConsumerArguments(), isNoLocal(), isExclusive(), queues); if (this.declarationRetries != null) { consumer.setDeclarationRetries(this.declarationRetries); } if (getFailedDeclarationRetryInterval() > 0) { consumer.setFailedDeclarationRetryInterval(getFailedDeclarationRetryInterval()); } if (this.retryDeclarationInterval != null) { consumer.setRetryDeclarationInterval(this.retryDeclarationInterval); } if (getConsumerTagStrategy() != null) { consumer.setTagStrategy(getConsumerTagStrategy()); // NOSONAR never null here } consumer.setBackOffExecution(getRecoveryBackOff().start()); consumer.setShutdownTimeout(getShutdownTimeout()); consumer.setApplicationEventPublisher(getApplicationEventPublisher()); return consumer; }
public synchronized void stop() { if (this.abortStarted == 0) { // signal handle delivery to use offer this.abortStarted = System.currentTimeMillis(); } if (!this.cancelled()) { try { RabbitUtils.closeMessageConsumer(this.channel, getConsumerTags(), this.transactional); } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Error closing consumer " + this, e); } } } if (logger.isDebugEnabled()) { logger.debug("Closing Rabbit Channel: " + this.channel); } RabbitUtils.setPhysicalCloseRequired(this.channel, true); ConnectionFactoryUtils.releaseResources(this.resourceHolder); this.deliveryTags.clear(); this.consumers.clear(); this.queue.clear(); // in case we still have a client thread blocked }
@Test public void testPrefetchIsSetOnFailedPassiveDeclaration() throws IOException { ConnectionFactory connectionFactory = mock(ConnectionFactory.class); Connection connection = mock(Connection.class); Channel channel = mock(Channel.class); when(connectionFactory.createConnection()).thenReturn(connection); when(connection.createChannel(anyBoolean())).thenReturn(channel); when(channel.isOpen()).thenReturn(true); when(channel.queueDeclarePassive(anyString())) .then(invocation -> { String arg = invocation.getArgument(0); if ("good".equals(arg)) { return any(AMQP.Queue.DeclareOk.class); } else { throw new IOException(); } }); when(channel.basicConsume(anyString(), anyBoolean(), anyString(), anyBoolean(), anyBoolean(), anyMap(), any(Consumer.class))).thenReturn("consumerTag"); BlockingQueueConsumer blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeMode.AUTO, true, 20, "good", "bad"); blockingQueueConsumer.setDeclarationRetries(1); blockingQueueConsumer.setRetryDeclarationInterval(10); blockingQueueConsumer.setFailedDeclarationRetryInterval(10); blockingQueueConsumer.start(); verify(channel).basicQos(20); }
@Test public void testTransactionalLowLevel() throws Exception { RabbitTemplate template = new RabbitTemplate(); CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); connectionFactory.setHost("localhost"); connectionFactory.setPort(BrokerTestUtils.getPort()); template.setConnectionFactory(connectionFactory); BlockingQueueConsumer blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeMode.AUTO, true, 1, queue1.getName(), queue2.getName()); final String consumerTagPrefix = UUID.randomUUID().toString(); blockingQueueConsumer.setTagStrategy(queue -> consumerTagPrefix + '#' + queue); CountDownLatch latch = new CountDownLatch(2); List<ConsumeOkEvent> events = new ArrayList<>(); blockingQueueConsumer.setApplicationEventPublisher(e -> { if (e instanceof ConsumeOkEvent) { events.add((ConsumeOkEvent) e); latch.countDown(); } }); blockingQueueConsumer.start(); assertTrue(latch.await(10, TimeUnit.SECONDS)); assertThat(events.get(0).getConsumerTag(), equalTo(consumerTagPrefix + "#" + queue1.getName())); assertThat(events.get(1).getConsumerTag(), equalTo(consumerTagPrefix + "#" + queue2.getName())); blockingQueueConsumer.stop(); assertNull(template.receiveAndConvert(queue1.getName())); connectionFactory.destroy(); }
private boolean doReceiveAndExecute(BlockingQueueConsumer consumer) throws Exception { //NOSONAR Channel channel = consumer.getChannel(); Message message = consumer.nextMessage(this.receiveTimeout); if (message == null) { break; .getResource(getConnectionFactory()); if (resourceHolder != null) { consumer.clearDeliveryTags(); consumer.rollbackOnExceptionIfNecessary(ex); consumer.rollbackOnExceptionIfNecessary(ex); throw ex; return consumer.commitIfNecessary(isChannelLocallyTransacted());
private BlockingQueueConsumer createConsumer(RabbitAccessor accessor) { BlockingQueueConsumer consumer = new BlockingQueueConsumer( accessor.getConnectionFactory(), new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeMode.AUTO, true, 1, queue.getName()); consumer.start(); // wait for consumeOk... int n = 0; while (n++ < 100) { if (consumer.getConsumerTags().size() == 0) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } return consumer; }
@Test public void testNoLocalConsumerConfiguration() throws Exception { ConnectionFactory connectionFactory = mock(ConnectionFactory.class); Connection connection = mock(Connection.class); Channel channel = mock(Channel.class); when(connectionFactory.createConnection()).thenReturn(connection); when(connection.createChannel(anyBoolean())).thenReturn(channel); when(channel.isOpen()).thenReturn(true); final String queue = "testQ"; final boolean noLocal = true; BlockingQueueConsumer blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeMode.AUTO, true, 1, true, null, noLocal, false, queue); blockingQueueConsumer.start(); verify(channel) .basicConsume(eq(queue), eq(AcknowledgeMode.AUTO.isAutoAck()), eq(""), eq(noLocal), eq(false), anyMap(), any(Consumer.class)); blockingQueueConsumer.stop(); }
String tag = consumer.getConsumerTags().iterator().next(); assertNotNull(tag); consumer.stop(); String tag = consumer.getConsumerTags().iterator().next(); assertNotNull(tag); consumer.stop();
private void initialize() throws Throwable { // NOSONAR try { redeclareElementsIfNecessary(); this.consumer.start(); this.start.countDown(); handleStartupFailure(this.consumer.getBackOffExecution()); throw e; handleStartupFailure(this.consumer.getBackOffExecution()); throw possibleAuthException; handleStartupFailure(this.consumer.getBackOffExecution()); throw t; ConsumerChannelRegistry.registerConsumerChannel(this.consumer.getChannel(), getConnectionFactory());
willThrow(new IOException("Intentional cancel fail")).given(channel).basicCancel("consumer2"); final BlockingQueueConsumer blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeMode.AUTO, false, 1, "testQ1", "testQ2"); final CountDownLatch latch = new CountDownLatch(1); Executors.newSingleThreadExecutor().execute(() -> { blockingQueueConsumer.start(); while (true) { try { blockingQueueConsumer.nextMessage(1000);
@Test public void testSendAndReceiveWithNonDefaultExchange() throws Exception { final RabbitAdmin admin = new RabbitAdmin(connectionFactory); final TopicExchange exchange = new TopicExchange("topic"); admin.declareExchange(exchange); admin.declareBinding(BindingBuilder.bind(queue).to(exchange).with("*.end")); template.execute(channel -> { BlockingQueueConsumer consumer = createConsumer(template); String tag = consumer.getConsumerTags().iterator().next(); assertNotNull(tag); template.convertAndSend("topic", "foo", "message"); try { String result = getResult(consumer); assertEquals(null, result); template.convertAndSend("topic", "foo.end", "message"); result = getResult(consumer); assertEquals("message", result); } finally { consumer.getChannel().basicCancel(tag); } return null; }); admin.deleteExchange("topic"); }
@Test public void testAvoidHangAMQP_508() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost"); String longName = new String(new byte[300]).replace('\u0000', 'x'); BlockingQueueConsumer blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeMode.AUTO, true, 1, longName, "foobar"); try { blockingQueueConsumer.start(); fail("expected exception"); } catch (FatalListenerStartupException e) { assertThat(e.getCause(), instanceOf(IllegalArgumentException.class)); } connectionFactory.destroy(); }
private void testRequeueOrNotDefaultNo(Exception ex, boolean expectedRequeue) throws Exception { ConnectionFactory connectionFactory = mock(ConnectionFactory.class); Channel channel = mock(Channel.class); BlockingQueueConsumer blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<BlockingQueueConsumer>(), AcknowledgeMode.AUTO, true, 1, false, "testQ"); testRequeueOrNotGuts(ex, expectedRequeue, channel, blockingQueueConsumer); }
new RabbitResourceHolder(consumer.getChannel(), false), getConnectionFactory(), true);
private String getResult(final BlockingQueueConsumer consumer) throws InterruptedException { Message response = consumer.nextMessage(2000L); if (response == null) { return null; } return (String) new SimpleMessageConverter().fromMessage(response); }
private void testRequeueOrNotGuts(Exception ex, boolean expectedRequeue, Channel channel, BlockingQueueConsumer blockingQueueConsumer) throws Exception { DirectFieldAccessor dfa = new DirectFieldAccessor(blockingQueueConsumer); dfa.setPropertyValue("channel", channel); Set<Long> deliveryTags = new HashSet<Long>(); deliveryTags.add(1L); dfa.setPropertyValue("deliveryTags", deliveryTags); blockingQueueConsumer.rollbackOnExceptionIfNecessary(ex); verify(channel).basicNack(1L, true, expectedRequeue); }
@Test public void testAlwaysCancelAutoRecoverConsumer() throws IOException { ConnectionFactory connectionFactory = mock(ConnectionFactory.class); Connection connection = mock(Connection.class); ChannelProxy channel = mock(ChannelProxy.class); Channel rabbitChannel = mock(AutorecoveringChannel.class); when(channel.getTargetChannel()).thenReturn(rabbitChannel); when(connectionFactory.createConnection()).thenReturn(connection); when(connection.createChannel(anyBoolean())).thenReturn(channel); final AtomicBoolean isOpen = new AtomicBoolean(true); doReturn(isOpen.get()).when(channel).isOpen(); when(channel.queueDeclarePassive(anyString())) .then(invocation -> mock(AMQP.Queue.DeclareOk.class)); doAnswer(i -> { ((Consumer) i.getArgument(6)).handleConsumeOk("consumerTag"); return "consumerTag"; }).when(channel).basicConsume(anyString(), anyBoolean(), anyString(), anyBoolean(), anyBoolean(), anyMap(), any(Consumer.class)); BlockingQueueConsumer blockingQueueConsumer = new BlockingQueueConsumer(connectionFactory, new DefaultMessagePropertiesConverter(), new ActiveObjectCounter<>(), AcknowledgeMode.AUTO, true, 2, "test"); blockingQueueConsumer.setDeclarationRetries(1); blockingQueueConsumer.setRetryDeclarationInterval(10); blockingQueueConsumer.setFailedDeclarationRetryInterval(10); blockingQueueConsumer.start(); verify(channel).basicQos(2); isOpen.set(false); blockingQueueConsumer.stop(); verify(channel).basicCancel("consumerTag"); }
private boolean doReceiveAndExecute(BlockingQueueConsumer consumer) throws Exception { //NOSONAR Channel channel = consumer.getChannel(); Message message = consumer.nextMessage(this.receiveTimeout); if (message == null) { break; .getResource(getConnectionFactory()); if (resourceHolder != null) { consumer.clearDeliveryTags(); consumer.rollbackOnExceptionIfNecessary(ex); consumer.rollbackOnExceptionIfNecessary(ex); throw ex; return consumer.commitIfNecessary(isChannelLocallyTransacted());
@Test public void testSendAndReceiveWithFanout() throws Exception { RabbitAdmin admin = new RabbitAdmin(connectionFactory); FanoutExchange exchange = new FanoutExchange("fanout"); admin.declareExchange(exchange); template.setExchange(exchange.getName()); admin.declareBinding(BindingBuilder.bind(queue).to(exchange)); template.execute(channel -> { BlockingQueueConsumer consumer = createConsumer(template); String tag = consumer.getConsumerTags().iterator().next(); assertNotNull(tag); try { template.convertAndSend("message"); String result = getResult(consumer); assertEquals("message", result); } finally { consumer.stop(); } return null; }); admin.deleteExchange("fanout"); }