/* * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.integration.amqp.dsl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import org.junit.AfterClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.amqp.core.AmqpTemplate; import org.springframework.amqp.core.AnonymousQueue; import org.springframework.amqp.core.MessageDeliveryMode; import org.springframework.amqp.core.Queue; import org.springframework.amqp.rabbit.AsyncRabbitTemplate; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.junit.BrokerRunning; import org.springframework.amqp.rabbit.listener.DirectMessageListenerContainer; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.integration.amqp.channel.AbstractAmqpChannel; import org.springframework.integration.amqp.inbound.AmqpInboundGateway; import org.springframework.integration.amqp.support.AmqpHeaderMapper; import org.springframework.integration.amqp.support.DefaultAmqpHeaderMapper; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.config.EnableIntegration; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.dsl.IntegrationFlowBuilder; import org.springframework.integration.dsl.IntegrationFlows; import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.PollableChannel; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; /** * @author Artem Bilan * @author Gary Russell * @since 5.0 */ @RunWith(SpringRunner.class) @DirtiesContext public class AmqpTests { @ClassRule public static BrokerRunning brokerRunning = BrokerRunning.isRunning(); @Autowired private ConnectionFactory rabbitConnectionFactory; @Autowired private AmqpTemplate amqpTemplate; @Autowired @Qualifier("queue") private Queue amqpQueue; @Autowired private AmqpInboundGateway amqpInboundGateway; @AfterClass public static void tearDown() { brokerRunning.removeTestQueues("amqpOutboundInput", "amqpReplyChannel", "asyncReplies", "defaultReplyTo", "si.dsl.test", "testTemplateChannelTransacted"); } @Test public void testAmqpInboundGatewayFlow() throws Exception { Object result = this.amqpTemplate.convertSendAndReceive(this.amqpQueue.getName(), "world"); assertEquals("HELLO WORLD", result); this.amqpInboundGateway.stop(); //INTEXT-209 this.amqpInboundGateway.start(); this.amqpTemplate.convertAndSend(this.amqpQueue.getName(), "world"); ((RabbitTemplate) this.amqpTemplate).setReceiveTimeout(10000); result = this.amqpTemplate.receiveAndConvert("defaultReplyTo"); assertEquals("HELLO WORLD", result); assertSame(this.amqpTemplate, TestUtils.getPropertyValue(this.amqpInboundGateway, "amqpTemplate")); } @Autowired @Qualifier("amqpOutboundInput") private MessageChannel amqpOutboundInput; @Autowired @Qualifier("amqpReplyChannel.channel") private PollableChannel amqpReplyChannel; @Test public void testAmqpOutboundFlow() throws Exception { this.amqpOutboundInput.send(MessageBuilder.withPayload("hello through the amqp") .setHeader("routingKey", "si.dsl.test") .build()); Message<?> receive = null; int i = 0; do { receive = this.amqpReplyChannel.receive(); if (receive != null) { break; } Thread.sleep(100); i++; } while (i < 10); assertNotNull(receive); assertEquals("HELLO THROUGH THE AMQP", receive.getPayload()); } @Test public void testTemplateChannelTransacted() { IntegrationFlowBuilder flow = IntegrationFlows.from(Amqp.channel("testTemplateChannelTransacted", this.rabbitConnectionFactory) .autoStartup(false) .templateChannelTransacted(true)); assertTrue(TestUtils.getPropertyValue(flow, "currentMessageChannel.amqpTemplate.transactional", Boolean.class)); } @Autowired @Qualifier("amqpAsyncOutboundFlow.input") private MessageChannel amqpAsyncOutboundFlowInput; @Test public void testAmqpAsyncOutboundGatewayFlow() throws Exception { QueueChannel replyChannel = new QueueChannel(); this.amqpAsyncOutboundFlowInput.send(MessageBuilder.withPayload("async gateway") .setReplyChannel(replyChannel) .build()); Message<?> receive = replyChannel.receive(10000); assertNotNull(receive); assertEquals("HELLO ASYNC GATEWAY", receive.getPayload()); } @Autowired private AbstractAmqpChannel unitChannel; @Autowired private AmqpHeaderMapper mapperIn; @Autowired private AmqpHeaderMapper mapperOut; @Test public void unitTestChannel() { assertEquals(MessageDeliveryMode.NON_PERSISTENT, TestUtils.getPropertyValue(this.unitChannel, "defaultDeliveryMode")); assertSame(this.mapperIn, TestUtils.getPropertyValue(this.unitChannel, "inboundHeaderMapper")); assertSame(this.mapperOut, TestUtils.getPropertyValue(this.unitChannel, "outboundHeaderMapper")); assertTrue(TestUtils.getPropertyValue(this.unitChannel, "extractPayload", Boolean.class)); } @Configuration @EnableIntegration public static class ContextConfiguration { @Bean public ConnectionFactory rabbitConnectionFactory() { return new CachingConnectionFactory("localhost"); } @Bean public RabbitTemplate amqpTemplate() { return new RabbitTemplate(rabbitConnectionFactory()); } @Bean public RabbitAdmin amqpAdmin() { return new RabbitAdmin(rabbitConnectionFactory()); } @Bean public Queue queue() { return new AnonymousQueue(); } @Bean public Queue defaultReplyTo() { return new Queue("defaultReplyTo"); } @Bean public IntegrationFlow amqpFlow(ConnectionFactory rabbitConnectionFactory, AmqpTemplate amqpTemplate) { return IntegrationFlows .from(Amqp.inboundGateway(rabbitConnectionFactory, amqpTemplate, queue()) .id("amqpInboundGateway") .configureContainer(c -> c .recoveryInterval(5000) .concurrentConsumers(1)) .defaultReplyTo(defaultReplyTo().getName())) .transform("hello "::concat) .transform(String.class, String::toUpperCase) .get(); } // syntax only public IntegrationFlow amqpDMLCFlow(ConnectionFactory rabbitConnectionFactory, AmqpTemplate amqpTemplate) { return IntegrationFlows .from(Amqp.inboundGateway(new DirectMessageListenerContainer()) .id("amqpInboundGateway") .configureContainer(c -> c .recoveryInterval(5000) .consumersPerQueue(1)) .defaultReplyTo(defaultReplyTo().getName())) .transform("hello "::concat) .transform(String.class, String::toUpperCase) .get(); } @Bean public IntegrationFlow amqpOutboundFlow(ConnectionFactory rabbitConnectionFactory, AmqpTemplate amqpTemplate) { return IntegrationFlows.from(Amqp.channel("amqpOutboundInput", rabbitConnectionFactory)) .handle(Amqp.outboundAdapter(amqpTemplate).routingKeyExpression("headers.routingKey")) .get(); } @Bean public Queue fooQueue() { return new Queue("si.dsl.test"); } @Bean public Queue amqpReplyChannel() { return new Queue("amqpReplyChannel"); } @Bean public IntegrationFlow amqpInboundFlow(ConnectionFactory rabbitConnectionFactory) { return IntegrationFlows.from(Amqp.inboundAdapter(rabbitConnectionFactory, fooQueue())) .transform(String.class, String::toUpperCase) .channel(Amqp.pollableChannel(rabbitConnectionFactory) .queueName("amqpReplyChannel") .channelTransacted(true)) .get(); } @Bean public Queue asyncReplies() { return new Queue("asyncReplies"); } @Bean public AsyncRabbitTemplate asyncRabbitTemplate(ConnectionFactory rabbitConnectionFactory) { return new AsyncRabbitTemplate(rabbitConnectionFactory, "", "", "asyncReplies"); } @Bean public IntegrationFlow amqpAsyncOutboundFlow(AsyncRabbitTemplate asyncRabbitTemplate) { return f -> f .handle(Amqp.asyncOutboundGateway(asyncRabbitTemplate) .routingKeyFunction(m -> queue().getName())); } @Bean public AbstractAmqpChannel unitChannel(ConnectionFactory rabbitConnectionFactory) { return Amqp.pollableChannel(rabbitConnectionFactory) .queueName("si.dsl.test") .channelTransacted(true) .extractPayload(true) .inboundHeaderMapper(mapperIn()) .outboundHeaderMapper(mapperOut()) .defaultDeliveryMode(MessageDeliveryMode.NON_PERSISTENT) .get(); } @Bean public AmqpHeaderMapper mapperIn() { return DefaultAmqpHeaderMapper.inboundMapper(); } @Bean public AmqpHeaderMapper mapperOut() { return DefaultAmqpHeaderMapper.outboundMapper(); } } }