Search in sources :

Example 21 with SimpleMessageListenerContainer

use of org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer in project spring-integration by spring-projects.

the class AsyncAmqpGatewayTests method testConfirmsAndReturns.

@Test
public void testConfirmsAndReturns() throws Exception {
    CachingConnectionFactory ccf = new CachingConnectionFactory("localhost");
    ccf.setPublisherConfirms(true);
    ccf.setPublisherReturns(true);
    RabbitTemplate template = new RabbitTemplate(ccf);
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(ccf);
    container.setBeanName("replyContainer");
    container.setQueueNames("asyncRQ1");
    container.afterPropertiesSet();
    container.start();
    AsyncRabbitTemplate asyncTemplate = new AsyncRabbitTemplate(template, container);
    asyncTemplate.setEnableConfirms(true);
    asyncTemplate.setMandatory(true);
    SimpleMessageListenerContainer receiver = new SimpleMessageListenerContainer(ccf);
    receiver.setBeanName("receiver");
    receiver.setQueueNames("asyncQ1");
    final CountDownLatch waitForAckBeforeReplying = new CountDownLatch(1);
    MessageListenerAdapter messageListener = new MessageListenerAdapter((ReplyingMessageListener<String, String>) foo -> {
        try {
            waitForAckBeforeReplying.await(10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return foo.toUpperCase();
    });
    receiver.setMessageListener(messageListener);
    receiver.afterPropertiesSet();
    receiver.start();
    AsyncAmqpOutboundGateway gateway = new AsyncAmqpOutboundGateway(asyncTemplate);
    Log logger = spy(TestUtils.getPropertyValue(gateway, "logger", Log.class));
    given(logger.isDebugEnabled()).willReturn(true);
    final CountDownLatch replyTimeoutLatch = new CountDownLatch(1);
    willAnswer(invocation -> {
        invocation.callRealMethod();
        replyTimeoutLatch.countDown();
        return null;
    }).given(logger).debug(startsWith("Reply not required and async timeout for"));
    new DirectFieldAccessor(gateway).setPropertyValue("logger", logger);
    QueueChannel outputChannel = new QueueChannel();
    outputChannel.setBeanName("output");
    QueueChannel returnChannel = new QueueChannel();
    returnChannel.setBeanName("returns");
    QueueChannel ackChannel = new QueueChannel();
    ackChannel.setBeanName("acks");
    QueueChannel errorChannel = new QueueChannel();
    errorChannel.setBeanName("errors");
    gateway.setOutputChannel(outputChannel);
    gateway.setReturnChannel(returnChannel);
    gateway.setConfirmAckChannel(ackChannel);
    gateway.setConfirmNackChannel(ackChannel);
    gateway.setConfirmCorrelationExpressionString("#this");
    gateway.setExchangeName("");
    gateway.setRoutingKey("asyncQ1");
    gateway.setBeanFactory(mock(BeanFactory.class));
    gateway.afterPropertiesSet();
    gateway.start();
    Message<?> message = MessageBuilder.withPayload("foo").setErrorChannel(errorChannel).build();
    gateway.handleMessage(message);
    Message<?> ack = ackChannel.receive(10000);
    assertNotNull(ack);
    assertEquals("foo", ack.getPayload());
    assertEquals(true, ack.getHeaders().get(AmqpHeaders.PUBLISH_CONFIRM));
    waitForAckBeforeReplying.countDown();
    Message<?> received = outputChannel.receive(10000);
    assertNotNull(received);
    assertEquals("FOO", received.getPayload());
    // timeout tests
    asyncTemplate.setReceiveTimeout(10);
    receiver.setMessageListener(message1 -> {
    });
    // reply timeout with no requiresReply
    message = MessageBuilder.withPayload("bar").setErrorChannel(errorChannel).build();
    gateway.handleMessage(message);
    assertTrue(replyTimeoutLatch.await(10, TimeUnit.SECONDS));
    // reply timeout with requiresReply
    gateway.setRequiresReply(true);
    message = MessageBuilder.withPayload("baz").setErrorChannel(errorChannel).build();
    gateway.handleMessage(message);
    received = errorChannel.receive(10000);
    assertThat(received, instanceOf(ErrorMessage.class));
    ErrorMessage error = (ErrorMessage) received;
    assertThat(error.getPayload(), instanceOf(MessagingException.class));
    assertThat(error.getPayload().getCause(), instanceOf(AmqpReplyTimeoutException.class));
    asyncTemplate.setReceiveTimeout(30000);
    receiver.setMessageListener(messageListener);
    // error on sending result
    DirectChannel errorForce = new DirectChannel();
    errorForce.setBeanName("errorForce");
    errorForce.subscribe(message1 -> {
        throw new RuntimeException("intentional");
    });
    gateway.setOutputChannel(errorForce);
    message = MessageBuilder.withPayload("qux").setErrorChannel(errorChannel).build();
    gateway.handleMessage(message);
    received = errorChannel.receive(10000);
    assertThat(received, instanceOf(ErrorMessage.class));
    error = (ErrorMessage) received;
    assertThat(error.getPayload(), instanceOf(MessagingException.class));
    assertEquals("QUX", ((MessagingException) error.getPayload()).getFailedMessage().getPayload());
    gateway.setRoutingKey(UUID.randomUUID().toString());
    message = MessageBuilder.withPayload("fiz").setErrorChannel(errorChannel).build();
    gateway.handleMessage(message);
    Message<?> returned = returnChannel.receive(10000);
    assertNotNull(returned);
    assertThat(returned, instanceOf(ErrorMessage.class));
    assertThat(returned.getPayload(), instanceOf(ReturnedAmqpMessageException.class));
    ReturnedAmqpMessageException payload = (ReturnedAmqpMessageException) returned.getPayload();
    assertEquals("fiz", payload.getFailedMessage().getPayload());
    ackChannel.receive(10000);
    ackChannel.purge(null);
    asyncTemplate = mock(AsyncRabbitTemplate.class);
    RabbitMessageFuture future = asyncTemplate.new RabbitMessageFuture(null, null);
    willReturn(future).given(asyncTemplate).sendAndReceive(anyString(), anyString(), any(org.springframework.amqp.core.Message.class));
    DirectFieldAccessor dfa = new DirectFieldAccessor(future);
    dfa.setPropertyValue("nackCause", "nacknack");
    SettableListenableFuture<Boolean> confirmFuture = new SettableListenableFuture<Boolean>();
    confirmFuture.set(false);
    dfa.setPropertyValue("confirm", confirmFuture);
    new DirectFieldAccessor(gateway).setPropertyValue("template", asyncTemplate);
    message = MessageBuilder.withPayload("buz").setErrorChannel(errorChannel).build();
    gateway.handleMessage(message);
    ack = ackChannel.receive(10000);
    assertNotNull(ack);
    assertThat(returned, instanceOf(ErrorMessage.class));
    assertThat(returned.getPayload(), instanceOf(ReturnedAmqpMessageException.class));
    NackedAmqpMessageException nack = (NackedAmqpMessageException) ack.getPayload();
    assertEquals("buz", nack.getFailedMessage().getPayload());
    assertEquals("nacknack", nack.getNackReason());
    asyncTemplate.stop();
    receiver.stop();
    ccf.destroy();
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) QueueChannel(org.springframework.integration.channel.QueueChannel) MessagingException(org.springframework.messaging.MessagingException) SimpleMessageListenerContainer(org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer) AsyncRabbitTemplate(org.springframework.amqp.rabbit.AsyncRabbitTemplate) SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) DirectFieldAccessor(org.springframework.beans.DirectFieldAccessor) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Mockito.spy(org.mockito.Mockito.spy) ReturnedAmqpMessageException(org.springframework.integration.amqp.support.ReturnedAmqpMessageException) Assert.assertThat(org.junit.Assert.assertThat) MessageBuilder(org.springframework.integration.support.MessageBuilder) BDDMockito.willReturn(org.mockito.BDDMockito.willReturn) AmqpReplyTimeoutException(org.springframework.amqp.core.AmqpReplyTimeoutException) RabbitMessageFuture(org.springframework.amqp.rabbit.AsyncRabbitTemplate.RabbitMessageFuture) BDDMockito.given(org.mockito.BDDMockito.given) CachingConnectionFactory(org.springframework.amqp.rabbit.connection.CachingConnectionFactory) BrokerRunning(org.springframework.amqp.rabbit.junit.BrokerRunning) MessageListenerAdapter(org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter) ReplyingMessageListener(org.springframework.amqp.rabbit.listener.adapter.ReplyingMessageListener) Message(org.springframework.messaging.Message) ClassRule(org.junit.ClassRule) RabbitTemplate(org.springframework.amqp.rabbit.core.RabbitTemplate) AfterClass(org.junit.AfterClass) ArgumentMatchers.startsWith(org.mockito.ArgumentMatchers.startsWith) Assert.assertNotNull(org.junit.Assert.assertNotNull) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) UUID(java.util.UUID) BDDMockito.willAnswer(org.mockito.BDDMockito.willAnswer) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) TestUtils(org.springframework.amqp.utils.test.TestUtils) NackedAmqpMessageException(org.springframework.integration.amqp.support.NackedAmqpMessageException) Rule(org.junit.Rule) Log4j2LevelAdjuster(org.springframework.integration.test.rule.Log4j2LevelAdjuster) BeanFactory(org.springframework.beans.factory.BeanFactory) Log(org.apache.commons.logging.Log) AmqpHeaders(org.springframework.amqp.support.AmqpHeaders) DirectChannel(org.springframework.integration.channel.DirectChannel) Assert.assertEquals(org.junit.Assert.assertEquals) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Mockito.mock(org.mockito.Mockito.mock) SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) QueueChannel(org.springframework.integration.channel.QueueChannel) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Message(org.springframework.messaging.Message) DirectChannel(org.springframework.integration.channel.DirectChannel) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) AmqpReplyTimeoutException(org.springframework.amqp.core.AmqpReplyTimeoutException) ReturnedAmqpMessageException(org.springframework.integration.amqp.support.ReturnedAmqpMessageException) BeanFactory(org.springframework.beans.factory.BeanFactory) NackedAmqpMessageException(org.springframework.integration.amqp.support.NackedAmqpMessageException) AsyncRabbitTemplate(org.springframework.amqp.rabbit.AsyncRabbitTemplate) RabbitTemplate(org.springframework.amqp.rabbit.core.RabbitTemplate) AsyncRabbitTemplate(org.springframework.amqp.rabbit.AsyncRabbitTemplate) Log(org.apache.commons.logging.Log) MessagingException(org.springframework.messaging.MessagingException) SimpleMessageListenerContainer(org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer) CountDownLatch(java.util.concurrent.CountDownLatch) MessageListenerAdapter(org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter) RabbitMessageFuture(org.springframework.amqp.rabbit.AsyncRabbitTemplate.RabbitMessageFuture) DirectFieldAccessor(org.springframework.beans.DirectFieldAccessor) CachingConnectionFactory(org.springframework.amqp.rabbit.connection.CachingConnectionFactory) ErrorMessage(org.springframework.messaging.support.ErrorMessage) Test(org.junit.Test)

Example 22 with SimpleMessageListenerContainer

use of org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer in project spring-integration by spring-projects.

the class OutboundEndpointTests method testAsyncDelayExpression.

@Test
public void testAsyncDelayExpression() {
    ConnectionFactory connectionFactory = mock(ConnectionFactory.class);
    AsyncRabbitTemplate amqpTemplate = spy(new AsyncRabbitTemplate(new RabbitTemplate(connectionFactory), new SimpleMessageListenerContainer(connectionFactory), "replyTo"));
    amqpTemplate.setTaskScheduler(mock(TaskScheduler.class));
    AsyncAmqpOutboundGateway gateway = new AsyncAmqpOutboundGateway(amqpTemplate);
    willAnswer(invocation -> amqpTemplate.new RabbitMessageFuture("foo", invocation.getArgument(2))).given(amqpTemplate).sendAndReceive(anyString(), anyString(), any(Message.class));
    gateway.setExchangeName("foo");
    gateway.setRoutingKey("bar");
    gateway.setDelayExpressionString("42");
    gateway.setBeanFactory(mock(BeanFactory.class));
    gateway.setOutputChannel(new NullChannel());
    gateway.afterPropertiesSet();
    gateway.start();
    ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
    gateway.handleMessage(new GenericMessage<>("foo"));
    verify(amqpTemplate).sendAndReceive(eq("foo"), eq("bar"), captor.capture());
    assertThat(captor.getValue().getMessageProperties().getDelay(), equalTo(42));
}
Also used : AsyncRabbitTemplate(org.springframework.amqp.rabbit.AsyncRabbitTemplate) RabbitTemplate(org.springframework.amqp.rabbit.core.RabbitTemplate) AsyncRabbitTemplate(org.springframework.amqp.rabbit.AsyncRabbitTemplate) ConnectionFactory(org.springframework.amqp.rabbit.connection.ConnectionFactory) Message(org.springframework.amqp.core.Message) GenericMessage(org.springframework.messaging.support.GenericMessage) SimpleMessageListenerContainer(org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer) BeanFactory(org.springframework.beans.factory.BeanFactory) TaskScheduler(org.springframework.scheduling.TaskScheduler) NullChannel(org.springframework.integration.channel.NullChannel) Test(org.junit.Test)

Example 23 with SimpleMessageListenerContainer

use of org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer in project spring-integration by spring-projects.

the class ChannelTests method channelDeclarationTests.

/*
	 * Verify queue is declared if not present and not declared if it is already present.
	 */
@Test
public void channelDeclarationTests() {
    RabbitAdmin admin = new RabbitAdmin(this.connectionFactory);
    admin.deleteQueue("implicit");
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(this.connectionFactory);
    container.setAutoStartup(false);
    AmqpTemplate amqpTemplate = mock(AmqpTemplate.class);
    PointToPointSubscribableAmqpChannel channel = new PointToPointSubscribableAmqpChannel("implicit", container, amqpTemplate);
    channel.setBeanFactory(mock(BeanFactory.class));
    channel.afterPropertiesSet();
    channel.onCreate(null);
    assertNotNull(admin.getQueueProperties("implicit"));
    admin.deleteQueue("explicit");
    channel.setQueueName("explicit");
    channel.afterPropertiesSet();
    channel.onCreate(null);
    assertNotNull(admin.getQueueProperties("explicit"));
    admin.deleteQueue("explicit");
    // verify no declaration if exists with non-standard props
    admin.declareQueue(new Queue("explicit", false));
    channel.afterPropertiesSet();
    channel.onCreate(null);
    assertNotNull(admin.getQueueProperties("explicit"));
    admin.deleteQueue("explicit");
}
Also used : SimpleMessageListenerContainer(org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer) BeanFactory(org.springframework.beans.factory.BeanFactory) RabbitAdmin(org.springframework.amqp.rabbit.core.RabbitAdmin) Queue(org.springframework.amqp.core.Queue) AmqpTemplate(org.springframework.amqp.core.AmqpTemplate) Test(org.junit.Test)

Example 24 with SimpleMessageListenerContainer

use of org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer in project spring-integration by spring-projects.

the class AmqpChannelFactoryBean method createContainer.

private AbstractMessageListenerContainer createContainer() throws Exception {
    AbstractMessageListenerContainer container;
    if (this.consumersPerQueue == null) {
        SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer();
        if (this.concurrentConsumers != null) {
            smlc.setConcurrentConsumers(this.concurrentConsumers);
        }
        if (this.receiveTimeout != null) {
            smlc.setReceiveTimeout(this.receiveTimeout);
        }
        if (this.txSize != null) {
            smlc.setTxSize(this.txSize);
        }
        container = smlc;
    } else {
        DirectMessageListenerContainer dmlc = new DirectMessageListenerContainer();
        dmlc.setConsumersPerQueue(this.consumersPerQueue);
        container = dmlc;
    }
    if (this.acknowledgeMode != null) {
        container.setAcknowledgeMode(this.acknowledgeMode);
    }
    if (!ObjectUtils.isEmpty(this.adviceChain)) {
        container.setAdviceChain(this.adviceChain);
    }
    container.setAutoStartup(this.autoStartup);
    container.setChannelTransacted(this.channelTransacted);
    container.setConnectionFactory(this.connectionFactory);
    if (this.errorHandler != null) {
        container.setErrorHandler(this.errorHandler);
    }
    if (this.exposeListenerChannel != null) {
        container.setExposeListenerChannel(this.exposeListenerChannel);
    }
    if (this.messagePropertiesConverter != null) {
        container.setMessagePropertiesConverter(this.messagePropertiesConverter);
    }
    if (this.phase != null) {
        container.setPhase(this.phase);
    }
    if (this.prefetchCount != null) {
        container.setPrefetchCount(this.prefetchCount);
    }
    if (this.recoveryInterval != null) {
        container.setRecoveryInterval(this.recoveryInterval);
    }
    if (this.shutdownTimeout != null) {
        container.setShutdownTimeout(this.shutdownTimeout);
    }
    if (this.taskExecutor != null) {
        container.setTaskExecutor(this.taskExecutor);
    }
    if (this.transactionAttribute != null) {
        container.setTransactionAttribute(this.transactionAttribute);
    }
    if (this.transactionManager != null) {
        container.setTransactionManager(this.transactionManager);
    }
    if (this.missingQueuesFatal != null) {
        container.setMissingQueuesFatal(this.missingQueuesFatal);
    }
    return container;
}
Also used : DirectMessageListenerContainer(org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer) SimpleMessageListenerContainer(org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer) AbstractMessageListenerContainer(org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer)

Example 25 with SimpleMessageListenerContainer

use of org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer in project spring-integration by spring-projects.

the class Amqp method inboundGateway.

/**
 * Create an initial {@link AmqpInboundGatewaySpec}.
 * @param connectionFactory the connectionFactory.
 * @param amqpTemplate the {@link AmqpTemplate} to use.
 * @param queues the queues.
 * @return the AmqpInboundGatewaySpec.
 */
public static AmqpInboundGatewaySMLCSpec inboundGateway(ConnectionFactory connectionFactory, AmqpTemplate amqpTemplate, Queue... queues) {
    SimpleMessageListenerContainer listenerContainer = new SimpleMessageListenerContainer(connectionFactory);
    listenerContainer.setQueues(queues);
    return inboundGateway(listenerContainer, amqpTemplate);
}
Also used : SimpleMessageListenerContainer(org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer)

Aggregations

SimpleMessageListenerContainer (org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer)27 Test (org.junit.Test)13 ConnectionFactory (org.springframework.amqp.rabbit.connection.ConnectionFactory)10 BeanFactory (org.springframework.beans.factory.BeanFactory)8 DirectChannel (org.springframework.integration.channel.DirectChannel)8 QueueChannel (org.springframework.integration.channel.QueueChannel)8 Channel (com.rabbitmq.client.Channel)7 MessageProperties (org.springframework.amqp.core.MessageProperties)7 Connection (org.springframework.amqp.rabbit.connection.Connection)7 ChannelAwareMessageListener (org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener)7 Jackson2JsonMessageConverter (org.springframework.amqp.support.converter.Jackson2JsonMessageConverter)5 Bean (org.springframework.context.annotation.Bean)5 Message (org.springframework.messaging.Message)5 PollableChannel (org.springframework.messaging.PollableChannel)5 GenericMessage (org.springframework.messaging.support.GenericMessage)5 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)4 RabbitTemplate (org.springframework.amqp.rabbit.core.RabbitTemplate)4 AbstractMessageListenerContainer (org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer)4 MessageConversionException (org.springframework.amqp.support.converter.MessageConversionException)4 MessageConverter (org.springframework.amqp.support.converter.MessageConverter)4