/* * Copyright 2013-2014 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.xd.dirt.integration.bus; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.support.StaticApplicationContext; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.channel.PublishSubscribeChannel; import org.springframework.integration.scheduling.PollerMetadata; import org.springframework.integration.support.DefaultMessageBuilderFactory; import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.support.utils.IntegrationUtils; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessagingException; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.support.PeriodicTrigger; import org.springframework.xd.dirt.integration.bus.local.LocalMessageBus; /** * @author Mark Fisher * @author Gary Russell */ public class MessageBusAwareChannelResolverTests { private final StaticApplicationContext context = new StaticApplicationContext(); private volatile MessageBusAwareChannelResolver resolver; private volatile LocalMessageBus bus; @Before public void setupContext() throws Exception { this.bus = new LocalMessageBus(); this.bus.setApplicationContext(context); this.bus.afterPropertiesSet(); this.resolver = new MessageBusAwareChannelResolver(this.bus, null); this.resolver.setBeanFactory(context); context.getBeanFactory().registerSingleton("channelResolver", this.resolver); context.registerSingleton("other", DirectChannel.class); context.registerSingleton("taskScheduler", ThreadPoolTaskScheduler.class); context.registerSingleton(IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME, DefaultMessageBuilderFactory.class); context.refresh(); PollerMetadata poller = new PollerMetadata(); poller.setTrigger(new PeriodicTrigger(1000)); bus.setPoller(poller); } @Test public void resolveQueueChannel() { MessageChannel registered = resolver.resolveDestination("queue:foo"); DirectChannel testChannel = new DirectChannel(); final CountDownLatch latch = new CountDownLatch(1); final List<Message<?>> received = new ArrayList<Message<?>>(); testChannel.subscribe(new MessageHandler() { @Override public void handleMessage(Message<?> message) throws MessagingException { received.add(message); latch.countDown(); } }); bus.bindConsumer("queue:foo", testChannel, null); assertEquals(0, received.size()); registered.send(MessageBuilder.withPayload("hello").build()); try { assertTrue("latch timed out", latch.await(1, TimeUnit.SECONDS)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); fail("interrupted while awaiting latch"); } assertEquals(1, received.size()); assertEquals("hello", received.get(0).getPayload()); context.close(); } @Test public void resolveTopicChannel() { MessageChannel registered = resolver.resolveDestination("topic:bar"); PublishSubscribeChannel[] testChannels = { new PublishSubscribeChannel(), new PublishSubscribeChannel(), new PublishSubscribeChannel() }; final CountDownLatch latch = new CountDownLatch(testChannels.length); final List<Message<?>> received = new ArrayList<Message<?>>(); for (PublishSubscribeChannel testChannel : testChannels) { testChannel.subscribe(new MessageHandler() { @Override public void handleMessage(Message<?> message) throws MessagingException { received.add(message); latch.countDown(); } }); bus.bindPubSubConsumer("topic:bar", testChannel, null); } assertEquals(0, received.size()); registered.send(MessageBuilder.withPayload("hello").build()); try { assertTrue("latch timed out", latch.await(1, TimeUnit.SECONDS)); } catch (InterruptedException e) { Thread.currentThread().interrupt(); fail("interrupted while awaiting latch"); } assertEquals(3, received.size()); assertEquals("hello", received.get(0).getPayload()); assertEquals("hello", received.get(1).getPayload()); assertEquals("hello", received.get(2).getPayload()); context.close(); } @Test public void resolveNonRegisteredChannel() { MessageChannel other = resolver.resolveDestination("other"); assertSame(context.getBean("other"), other); } @Test public void propertyPassthrough() { Properties properties = new Properties(); MessageBus bus = mock(MessageBus.class); doReturn(new DirectChannel()).when(bus).bindDynamicProducer("queue:foo", properties); doReturn(new DirectChannel()).when(bus).bindDynamicPubSubProducer("topic:bar", properties); MessageBusAwareChannelResolver resolver = new MessageBusAwareChannelResolver(bus, properties); BeanFactory beanFactory = new DefaultListableBeanFactory(); resolver.setBeanFactory(beanFactory); resolver.resolveDestination("queue:foo"); resolver.resolveDestination("topic:bar"); verify(bus).bindDynamicProducer("queue:foo", properties); verify(bus).bindDynamicPubSubProducer("topic:bar", properties); } }