From 65102cc725a49cf1bd6c40cab65d5a95a79a2e84 Mon Sep 17 00:00:00 2001 From: Mark Fisher Date: Thu, 24 Dec 2009 01:59:08 +0000 Subject: [PATCH] INT-578 RecipientListRouter now accepts a channel Map with MessageSelector keys (no namespace support yet). --- .../router/RecipientListRouter.java | 48 ++++++++++++++----- .../router/RecipientListRouterTests.java | 11 +++-- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/router/RecipientListRouter.java b/org.springframework.integration/src/main/java/org/springframework/integration/router/RecipientListRouter.java index f7cba58170..30758f2b60 100644 --- a/org.springframework.integration/src/main/java/org/springframework/integration/router/RecipientListRouter.java +++ b/org.springframework.integration/src/main/java/org/springframework/integration/router/RecipientListRouter.java @@ -17,7 +17,11 @@ package org.springframework.integration.router; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import org.springframework.beans.factory.InitializingBean; @@ -28,13 +32,18 @@ import org.springframework.integration.core.MessageHeaders; import org.springframework.integration.handler.AbstractMessageHandler; import org.springframework.integration.message.MessageBuilder; import org.springframework.integration.message.MessageDeliveryException; +import org.springframework.integration.selector.MessageSelector; import org.springframework.util.Assert; /** - * A Message Router that sends Messages to a statically configured list of - * recipients. The recipients are provided as a list of {@link MessageChannel} - * instances. For dynamic recipient lists, consider instead using the @Router - * annotation or extending {@link AbstractChannelNameResolvingMessageRouter}. + * A Message Router that sends Messages to a list of recipient channels. The + * recipients can be provided as a static list of {@link MessageChannel} + * instances via the {@link #setChannels(List)} method, or for dynamic + * behavior, a map with {@link MessageSelector} instances as the keys and + * collections of channels as the values can be provided via the + * {@link #setChannelMap(Map)} method. For more advanced, programmatic control + * of dynamic recipient lists, consider using the @Router annotation or + * extending {@link AbstractChannelNameResolvingMessageRouter} instead. * * @author Mark Fisher */ @@ -44,17 +53,27 @@ public class RecipientListRouter extends AbstractMessageHandler implements Initi private volatile boolean applySequence; - private volatile List channels; + private volatile Map> channelMap; private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate(); public void setChannels(List channels) { - this.channels = channels; + Assert.notEmpty(channels, "channels must not be empty"); + MessageSelector selector = new MessageSelector() { + public boolean accept(Message message) { + return true; + } + }; + this.setChannelMap(Collections.singletonMap(selector, channels)); + } + + public void setChannelMap(Map> channelMap) { + this.channelMap = channelMap; } /** - * Set the timeout for sending a message to the resolved channel. By + * Set the timeout for sending a message to the resolved channel(s). By * default, there is no timeout, meaning the send will block indefinitely. */ public void setTimeout(long timeout) { @@ -84,15 +103,22 @@ public class RecipientListRouter extends AbstractMessageHandler implements Initi } public void afterPropertiesSet() { - Assert.notEmpty(this.channels, "a non-empty channel list is required"); + Assert.notEmpty(this.channelMap, "a non-empty channel map is required"); } @Override protected void handleMessageInternal(Message message) throws Exception { - List channelList = new ArrayList(this.channels); - int sequenceSize = channelList.size(); + List recipients = new ArrayList(); + Map> map = + new HashMap>(this.channelMap); + for (MessageSelector selector : map.keySet()) { + if (selector.accept(message)) { + recipients.addAll(map.get(selector)); + } + } + int sequenceSize = recipients.size(); int sequenceNumber = 1; - for (MessageChannel channel : channelList) { + for (MessageChannel channel : recipients) { final Message messageToSend = (!this.applySequence) ? message : MessageBuilder.fromMessage(message) .setSequenceNumber(sequenceNumber++) diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/router/RecipientListRouterTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/router/RecipientListRouterTests.java index bfc62efa85..3d7da11add 100644 --- a/org.springframework.integration/src/test/java/org/springframework/integration/router/RecipientListRouterTests.java +++ b/org.springframework.integration/src/test/java/org/springframework/integration/router/RecipientListRouterTests.java @@ -25,14 +25,17 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import org.junit.Test; + import org.springframework.beans.DirectFieldAccessor; import org.springframework.integration.channel.QueueChannel; import org.springframework.integration.core.Message; import org.springframework.integration.core.MessageChannel; import org.springframework.integration.message.MessageDeliveryException; import org.springframework.integration.message.StringMessage; +import org.springframework.integration.selector.MessageSelector; /** * @author Mark Fisher @@ -50,8 +53,10 @@ public class RecipientListRouterTests { RecipientListRouter router = new RecipientListRouter(); router.setChannels(channels); router.afterPropertiesSet(); - Collection channelList = (Collection) - new DirectFieldAccessor(router).getPropertyValue("channels"); + Map> channelMap = + (Map>) + new DirectFieldAccessor(router).getPropertyValue("channelMap"); + Collection channelList = channelMap.values().iterator().next(); assertEquals(2, channelList.size()); assertTrue(channelList.contains(channel1)); assertTrue(channelList.contains(channel2)); @@ -337,7 +342,6 @@ public class RecipientListRouterTests { public void nullChannelListRejected() { RecipientListRouter router = new RecipientListRouter(); router.setChannels(null); - router.afterPropertiesSet(); } @Test(expected = IllegalArgumentException.class) @@ -345,7 +349,6 @@ public class RecipientListRouterTests { RecipientListRouter router = new RecipientListRouter(); List channels = new ArrayList(); router.setChannels(channels); - router.afterPropertiesSet(); } @Test(expected = IllegalArgumentException.class)