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();
}
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));
}
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");
}
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;
}
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);
}
Aggregations