INT-578 RecipientListRouter now accepts a channel Map with MessageSelector keys (no namespace support yet).

This commit is contained in:
Mark Fisher
2009-12-24 01:59:08 +00:00
parent 5cabd501aa
commit 65102cc725
2 changed files with 44 additions and 15 deletions

View File

@@ -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<MessageChannel> channels;
private volatile Map<MessageSelector, ? extends Collection<MessageChannel>> channelMap;
private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate();
public void setChannels(List<MessageChannel> 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<MessageSelector, ? extends Collection<MessageChannel>> 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<MessageChannel> channelList = new ArrayList<MessageChannel>(this.channels);
int sequenceSize = channelList.size();
List<MessageChannel> recipients = new ArrayList<MessageChannel>();
Map<MessageSelector, Collection<MessageChannel>> map =
new HashMap<MessageSelector, Collection<MessageChannel>>(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++)

View File

@@ -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<MessageChannel> channelList = (Collection<MessageChannel>)
new DirectFieldAccessor(router).getPropertyValue("channels");
Map<MessageSelector, Collection<MessageChannel>> channelMap =
(Map<MessageSelector, Collection<MessageChannel>>)
new DirectFieldAccessor(router).getPropertyValue("channelMap");
Collection<MessageChannel> 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<MessageChannel> channels = new ArrayList<MessageChannel>();
router.setChannels(channels);
router.afterPropertiesSet();
}
@Test(expected = IllegalArgumentException.class)