@Override protected DirectMessageListenerContainer createContainerInstance() { return new DirectMessageListenerContainer(); }
/** * @param consumersPerQueue the consumersPerQueue. * @return the spec. * @see DirectMessageListenerContainer#setConsumersPerQueue(int) */ public DirectMessageListenerContainerSpec consumersPerQueue(int consumersPerQueue) { this.listenerContainer.setConsumersPerQueue(consumersPerQueue); return this; }
/** * @param ackTimeout the ack timeout. * @return the spec. * @see DirectMessageListenerContainer#setAckTimeout(long) */ public DirectMessageListenerContainerSpec ackTimeout(long ackTimeout) { this.listenerContainer.setAckTimeout(ackTimeout); return this; }
@Test public void testAdvice() throws Exception { CachingConnectionFactory cf = new CachingConnectionFactory("localhost"); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); container.setQueueNames(Q1, Q2); container.setConsumersPerQueue(2); final CountDownLatch latch = new CountDownLatch(2); container.setMessageListener(m -> latch.countDown()); final CountDownLatch adviceLatch = new CountDownLatch(2); MethodInterceptor advice = i -> { adviceLatch.countDown(); return i.proceed(); }; container.setAdviceChain(advice); container.setBeanName("advice"); container.setConsumerTagStrategy(new Tag()); container.afterPropertiesSet(); container.start(); RabbitTemplate template = new RabbitTemplate(cf); template.convertAndSend(Q1, "foo"); template.convertAndSend(Q1, "bar"); assertTrue(latch.await(10, TimeUnit.SECONDS)); assertTrue(adviceLatch.await(10, TimeUnit.SECONDS)); container.stop(); assertTrue(consumersOnQueue(Q1, 0)); assertTrue(consumersOnQueue(Q2, 0)); assertTrue(activeConsumerCount(container, 0)); assertEquals(0, TestUtils.getPropertyValue(container, "consumersByQueue", MultiValueMap.class).size()); cf.destroy(); }
protected void actualStart() { this.aborted = false; this.hasStopped = false; if (getPrefetchCount() < this.messagesPerAck) { setPrefetchCount(this.messagesPerAck); final String[] queueNames = getQueueNames(); checkMissingQueues(queueNames); long idleEventInterval = getIdleEventInterval(); if (this.taskScheduler == null) { afterPropertiesSet(); if (getFailedDeclarationRetryInterval() < this.monitorInterval) { this.monitorInterval = getFailedDeclarationRetryInterval(); final Map<String, Queue> namesToQueues = getQueueNamesToQueues(); this.lastRestartAttempt = System.currentTimeMillis(); startMonitor(idleEventInterval, namesToQueues); if (queueNames.length > 0) { doRedeclareElementsIfNecessary(); getTaskExecutor().execute(() -> { // NOSONAR never null here startConsumers(queueNames);
executor.afterPropertiesSet(); cf.setExecutor(executor); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); container.setConsumersPerQueue(2); container.setMessageListener(new MessageListenerAdapter((ReplyingMessageListener<String, String>) in -> { if ("foo".equals(in) || "bar".equals(in)) { return in.toUpperCase(); container.setBeanName("qManage"); container.setConsumerTagStrategy(new Tag()); container.afterPropertiesSet(); container.setQueues(new Queue(Q1)); assertArrayEquals(new String[] { Q1 }, container.getQueueNames()); container.start(); container.addQueues(new Queue(Q2)); assertTrue(consumersOnQueue(Q1, 2)); assertTrue(consumersOnQueue(Q2, 2)); assertEquals("FOO", template.convertSendAndReceive(Q1, "foo")); assertEquals("BAR", template.convertSendAndReceive(Q2, "bar")); container.removeQueues(new Queue(Q1), new Queue(Q2), new Queue("junk")); assertTrue(consumersOnQueue(Q1, 0)); assertTrue(consumersOnQueue(Q2, 0)); assertTrue(activeConsumerCount(container, 0)); container.stop(); assertTrue(consumersOnQueue(Q1, 0)); assertTrue(consumersOnQueue(Q2, 0));
}).given(channel).basicNack(19L, true, true); DirectMessageListenerContainer container = new DirectMessageListenerContainer(connectionFactory); container.setQueueNames("test"); container.setPrefetchCount(2); container.setMonitorInterval(100); container.setMessagesPerAck(10); container.setAckTimeout(100); container.setMessageListener(m -> { if (m.getMessageProperties().getDeliveryTag() == 19L) { throw new RuntimeException("TestNackAndPendingAcks"); container.afterPropertiesSet(); container.start();
}).given(channel).basicConsume(eq("foo"), anyBoolean(), anyString(), anyBoolean(), anyBoolean(), anyMap(), consumerCaptor.capture()); DirectMessageListenerContainer container = new DirectMessageListenerContainer(mockCF); container.setQueueNames("foo"); container.setBeanName("brokerLost"); container.setConsumerTagStrategy(q -> "tag"); container.setShutdownTimeout(1); container.setMonitorInterval(200); container.setFailedDeclarationRetryInterval(200); container.afterPropertiesSet(); container.start(); assertTrue(latch1.await(10, TimeUnit.SECONDS)); given(channel.isOpen()).willReturn(false); assertTrue(latch2.await(10, TimeUnit.SECONDS)); container.setShutdownTimeout(1); container.stop();
private void testRecoverDeletedQueueGuts(boolean autoDeclare) throws Exception { CachingConnectionFactory cf = new CachingConnectionFactory("localhost"); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); if (autoDeclare) { GenericApplicationContext context = new GenericApplicationContext(); context.getBeanFactory().registerSingleton("admin", admin); context.refresh(); container.setApplicationContext(context); container.setAutoDeclare(autoDeclare); container.setQueueNames(Q1, Q2); container.setConsumersPerQueue(2); container.setConsumersPerQueue(2); container.setMessageListener(m -> { }); container.setFailedDeclarationRetryInterval(500); container.setBeanName("deleteQauto=" + autoDeclare); container.setConsumerTagStrategy(new Tag()); container.afterPropertiesSet(); container.start(); assertTrue(consumersOnQueue(Q1, 2)); assertTrue(consumersOnQueue(Q2, 2)); assertTrue(consumersOnQueue(Q2, 2)); assertTrue(activeConsumerCount(container, 4)); container.stop(); assertTrue(consumersOnQueue(Q1, 0)); assertTrue(consumersOnQueue(Q2, 0));
@Test public void testNonManagedContainerStopsWhenConnectionFactoryDestroyed() throws Exception { CachingConnectionFactory cf = new CachingConnectionFactory("localhost"); ApplicationContext context = mock(ApplicationContext.class); cf.setApplicationContext(context); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); final CountDownLatch latch = new CountDownLatch(1); container.setMessageListener(m -> { latch.countDown(); }); container.setQueueNames(Q1); container.setBeanName("stopAfterDestroy"); container.setIdleEventInterval(500); container.setFailedDeclarationRetryInterval(500); container.afterPropertiesSet(); container.start(); new RabbitTemplate(cf).convertAndSend(Q1, "foo"); assertTrue(latch.await(10, TimeUnit.SECONDS)); cf.onApplicationEvent(new ContextClosedEvent(context)); cf.destroy(); int n = 0; while (n++ < 100 && container.isRunning()) { Thread.sleep(100); } assertFalse(container.isRunning()); }
@Test public void testEvents() throws Exception { CachingConnectionFactory cf = new CachingConnectionFactory("localhost"); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); container.setQueueNames(EQ1, EQ2); final List<Long> times = new ArrayList<>(); final CountDownLatch latch1 = new CountDownLatch(2); final CountDownLatch latch2 = new CountDownLatch(2); container.setApplicationEventPublisher(event -> { if (event instanceof ListenerContainerIdleEvent) { times.add(System.currentTimeMillis()); latch1.countDown(); } else if (event instanceof ListenerContainerConsumerTerminatedEvent) { latch2.countDown(); } }); container.setMessageListener(m -> { }); container.setIdleEventInterval(50L); container.setBeanName("events"); container.setConsumerTagStrategy(new Tag()); container.afterPropertiesSet(); container.start(); assertTrue(latch1.await(10, TimeUnit.SECONDS)); assertThat(times.get(1) - times.get(0), greaterThanOrEqualTo(50L)); brokerRunning.deleteQueues(EQ1, EQ2); assertTrue(latch2.await(10, TimeUnit.SECONDS)); container.stop(); cf.destroy(); }
@Test public void testContainerNotRecoveredAfterExhaustingRecoveryBackOff() throws Exception { ConnectionFactory mockCF = mock(ConnectionFactory.class); given(mockCF.createConnection()).willReturn(null).willThrow(new RuntimeException("intended - backOff test")); DirectMessageListenerContainer container = new DirectMessageListenerContainer(mockCF); container.setQueueNames("foo"); container.setRecoveryBackOff(new FixedBackOff(100, 3)); container.setMissingQueuesFatal(false); container.setBeanName("backOff"); container.setConsumerTagStrategy(new Tag()); container.afterPropertiesSet(); container.start(); // Since backOff exhausting makes listenerContainer as invalid (calls stop()), // it is enough to check the listenerContainer activity int n = 0; while (container.isActive() && n++ < 100) { Thread.sleep(100); } assertFalse(container.isActive()); }
@Test public void testDeferredAcks() throws Exception { CachingConnectionFactory cf = new CachingConnectionFactory("localhost"); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); final CountDownLatch latch = new CountDownLatch(2); container.setMessageListener(m -> { latch.countDown(); }); container.setQueueNames(Q1); container.setBeanName("deferredAcks"); container.setMessagesPerAck(2); container.afterPropertiesSet(); container.start(); RabbitTemplate rabbitTemplate = new RabbitTemplate(cf); rabbitTemplate.convertAndSend(Q1, "foo"); rabbitTemplate.convertAndSend(Q1, "bar"); assertTrue(latch.await(10, TimeUnit.SECONDS)); container.stop(); cf.destroy(); }
}).given(channel).basicCancel("consumerTag"); DirectMessageListenerContainer container = new DirectMessageListenerContainer(connectionFactory); container.setQueueNames("test1", "test2"); container.setPrefetchCount(2); container.setMonitorInterval(100); container.setFailedDeclarationRetryInterval(100); container.setRecoveryInterval(100); container.setShutdownTimeout(1); container.afterPropertiesSet(); container.start(); container.removeQueueNames("test1"); assertTrue(latch2.await(10, TimeUnit.SECONDS)); isOpen.set(true); anyMap(), any(Consumer.class)); container.stop();
@Override protected void initializeContainer(DirectMessageListenerContainer instance, RabbitListenerEndpoint endpoint) { super.initializeContainer(instance, endpoint); if (this.taskScheduler != null) { instance.setTaskScheduler(this.taskScheduler); } if (this.monitorInterval != null) { instance.setMonitorInterval(this.monitorInterval); } if (endpoint != null && endpoint.getConcurrency() != null) { try { instance.setConsumersPerQueue(Integer.parseInt(endpoint.getConcurrency())); } catch (NumberFormatException e) { throw new IllegalStateException("Failed to parse concurrency: " + e.getMessage(), e); } } else if (this.consumersPerQueue != null) { instance.setConsumersPerQueue(this.consumersPerQueue); } if (this.messagesPerAck != null) { instance.setMessagesPerAck(this.messagesPerAck); } if (this.ackTimeout != null) { instance.setAckTimeout(this.ackTimeout); } }
executor.afterPropertiesSet(); cf.setExecutor(executor); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); container.setConsumersPerQueue(2); container.setMessageListener(new MessageListenerAdapter((ReplyingMessageListener<String, String>) in -> { if ("foo".equals(in) || "bar".equals(in)) { return in.toUpperCase(); container.setBeanName("qManage"); container.setConsumerTagStrategy(new Tag()); container.afterPropertiesSet(); container.start(); container.addQueueNames(Q1, Q2); assertTrue(consumersOnQueue(Q1, 2)); assertTrue(consumersOnQueue(Q2, 2)); assertEquals("FOO", template.convertSendAndReceive(Q1, "foo")); assertEquals("BAR", template.convertSendAndReceive(Q2, "bar")); container.removeQueueNames(Q1, Q2, "junk"); assertTrue(consumersOnQueue(Q1, 0)); assertTrue(consumersOnQueue(Q2, 0)); assertTrue(activeConsumerCount(container, 0)); container.stop(); assertTrue(consumersOnQueue(Q1, 0)); assertTrue(consumersOnQueue(Q2, 0));
@Nullable private SimpleConsumer consume(String queue, Connection connection) { Channel channel = null; SimpleConsumer consumer = null; try { channel = connection.createChannel(isChannelTransacted()); channel.basicQos(getPrefetchCount()); consumer = new SimpleConsumer(connection, channel, queue); channel.queueDeclarePassive(queue); consumer.consumerTag = channel.basicConsume(queue, getAcknowledgeMode().isAutoAck(), (getConsumerTagStrategy() != null ? getConsumerTagStrategy().createConsumerTag(queue) : ""), // NOSONAR never null isNoLocal(), isExclusive(), getConsumerArguments(), consumer); } catch (AmqpApplicationContextClosedException e) { throw new AmqpConnectException(e); } catch (Exception e) { RabbitUtils.closeChannel(channel); RabbitUtils.closeConnection(connection); consumer = handleConsumeException(queue, consumer, e); } return consumer; }
@Test public void testNonManagedContainerDoesntStartWhenConnectionFactoryDestroyed() throws Exception { CachingConnectionFactory cf = new CachingConnectionFactory("localhost"); ApplicationContext context = mock(ApplicationContext.class); cf.setApplicationContext(context); cf.addConnectionListener(connection -> { cf.onApplicationEvent(new ContextClosedEvent(context)); cf.destroy(); }); DirectMessageListenerContainer container = new DirectMessageListenerContainer(cf); container.setMessageListener(m -> { }); container.setQueueNames(Q1); container.setBeanName("stopAfterDestroyBeforeStart"); container.afterPropertiesSet(); container.start(); int n = 0; while (n++ < 100 && container.isRunning()) { Thread.sleep(100); } assertFalse(container.isRunning()); }
private void doConsumeFromQueue(String queue) { if (!isActive()) { if (this.logger.isDebugEnabled()) { this.logger.debug("Consume from queue " + queue + " ignore, container stopping"); String routingLookupKey = getRoutingLookupKey(); if (routingLookupKey != null) { SimpleResourceHolder.bind(getRoutingConnectionFactory(), routingLookupKey); // NOSONAR both never null here connection = getConnectionFactory().createConnection(); addConsumerToRestart(new SimpleConsumer(null, null, queue)); throw e instanceof AmqpConnectException // NOSONAR exception type check ? (AmqpConnectException) e SimpleResourceHolder.unbind(getRoutingConnectionFactory()); // NOSONAR never null here SimpleConsumer consumer = consume(queue, connection); synchronized (this.consumersMonitor) { if (consumer != null) { this.logger.info(consumer + " started"); if (getApplicationEventPublisher() != null) { getApplicationEventPublisher().publishEvent(new AsyncConsumerStartedEvent(this, consumer));
DirectMessageListenerContainer container = new DirectMessageListenerContainer(this.connectionFactory); if (this.consumersPerQueue != null) { container.setConsumersPerQueue(this.consumersPerQueue); container.setTaskScheduler(this.taskScheduler); container.setMonitorInterval(this.monitorInterval);