diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/DslRecipientListRouter.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/DslRecipientListRouter.java index 6f52884..de77e15 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/DslRecipientListRouter.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/DslRecipientListRouter.java @@ -39,6 +39,11 @@ class DslRecipientListRouter extends RecipientListRouter { private final Map selectorRecipientMap = new HashMap(); + private final Map channelExpressionRecipientMap = new HashMap(); + + private final Map channelSelectorRecipientMap = + new HashMap(); + void add(String channelName, String expression) { this.expressionRecipientMap.put(channelName, expression); } @@ -47,12 +52,12 @@ class DslRecipientListRouter extends RecipientListRouter { this.selectorRecipientMap.put(channelName, selector); } - Map get() { - Map recipients = - new HashMap(this.expressionRecipientMap.size() + this.selectorRecipientMap.size()); - recipients.putAll(this.expressionRecipientMap); - recipients.putAll(this.selectorRecipientMap); - return recipients; + void add(MessageChannel channel, String expression) { + this.channelExpressionRecipientMap.put(channel, expression); + } + + void add(MessageChannel channel, MessageSelector selector) { + this.channelSelectorRecipientMap.put(channel, selector); } @Override @@ -67,13 +72,28 @@ class DslRecipientListRouter extends RecipientListRouter { this.selectorRecipientMap.put(recipient.getKey(), selector); } - List recipients = new ArrayList(this.selectorRecipientMap.size()); + for (Map.Entry recipient : this.channelExpressionRecipientMap.entrySet()) { + ExpressionEvaluatingSelector selector = null; + String expression = recipient.getValue(); + if (StringUtils.hasText(expression)) { + selector = new ExpressionEvaluatingSelector(expression); + selector.setBeanFactory(this.getBeanFactory()); + } + this.channelSelectorRecipientMap.put(recipient.getKey(), selector); + } + + List recipients = new ArrayList(this.selectorRecipientMap.size() + + this.channelSelectorRecipientMap.size()); for (Map.Entry entry : selectorRecipientMap.entrySet()) { recipients.add(new DslRecipient(new MessageChannelReference(entry.getKey()), entry.getValue())); } - this.setRecipients(recipients); + for (Map.Entry entry : channelSelectorRecipientMap.entrySet()) { + recipients.add(new Recipient(entry.getKey(), entry.getValue())); + } + + setRecipients(recipients); super.onInit(); } diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java index e8c756d..76e9087 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java @@ -630,7 +630,7 @@ public abstract class IntegrationFlowDefinition routerConfigurer) { - return this.routeToRecipients(routerConfigurer, null); + return routeToRecipients(routerConfigurer, null); } public B routeToRecipients(Consumer routerConfigurer, @@ -638,18 +638,17 @@ public abstract class IntegrationFlowDefinition B route(R router, Consumer> endpointConfigurer) { - return this.handle(router, endpointConfigurer); + return handle(router, endpointConfigurer); } public B gateway(String requestChannel) { diff --git a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/RecipientListRouterSpec.java b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/RecipientListRouterSpec.java index 4abb82f..a437e8d 100644 --- a/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/RecipientListRouterSpec.java +++ b/spring-integration-java-dsl/src/main/java/org/springframework/integration/dsl/RecipientListRouterSpec.java @@ -16,14 +16,23 @@ package org.springframework.integration.dsl; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.core.MessageSelector; +import org.springframework.integration.dsl.core.ComponentsRegistration; import org.springframework.integration.router.RecipientListRouter; import org.springframework.util.Assert; /** * @author Artem Bilan */ -public class RecipientListRouterSpec extends AbstractRouterSpec { +public class RecipientListRouterSpec extends AbstractRouterSpec + implements ComponentsRegistration { + + private final List subFlows = new ArrayList(); RecipientListRouterSpec() { super(new DslRecipientListRouter()); @@ -41,4 +50,31 @@ public class RecipientListRouterSpec extends AbstractRouterSpec getComponentsToRegister() { + return subFlows; + } + } diff --git a/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/flows/IntegrationFlowTests.java b/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/flows/IntegrationFlowTests.java index c9b5f0b..422be40 100644 --- a/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/flows/IntegrationFlowTests.java +++ b/spring-integration-java-dsl/src/test/java/org/springframework/integration/dsl/test/flows/IntegrationFlowTests.java @@ -231,6 +231,14 @@ public class IntegrationFlowTests { @Qualifier("recipientListInput") private MessageChannel recipientListInput; + @Autowired + @Qualifier("recipientListSubFlow1Result") + private PollableChannel recipientListSubFlow1Result; + + @Autowired + @Qualifier("recipientListSubFlow2Result") + private PollableChannel recipientListSubFlow2Result; + @Autowired @Qualifier("defaultOutputChannel") private PollableChannel defaultOutputChannel; @@ -687,6 +695,7 @@ public class IntegrationFlowTests { Message fooMessage = MessageBuilder.withPayload("fooPayload").setHeader("recipient", true).build(); Message barMessage = MessageBuilder.withPayload("barPayload").setHeader("recipient", true).build(); + Message bazMessage = new GenericMessage<>("baz"); Message badMessage = new GenericMessage<>("badPayload"); this.recipientListInput.send(fooMessage); @@ -696,21 +705,39 @@ public class IntegrationFlowTests { Message result1b = this.barChannel.receive(2000); assertNotNull(result1b); assertEquals("foo", result1b.getPayload()); + Message result1c = this.recipientListSubFlow1Result.receive(2000); + assertNotNull(result1c); + assertEquals("FOO", result1c.getPayload()); + assertNull(this.recipientListSubFlow2Result.receive(0)); this.recipientListInput.send(barMessage); assertNull(this.fooChannel.receive(0)); + assertNull(this.recipientListSubFlow2Result.receive(0)); Message result2b = this.barChannel.receive(2000); assertNotNull(result2b); assertEquals("bar", result2b.getPayload()); + Message result2c = this.recipientListSubFlow1Result.receive(2000); + assertNotNull(result1c); + assertEquals("BAR", result2c.getPayload()); + this.recipientListInput.send(bazMessage); + assertNull(this.fooChannel.receive(0)); + assertNull(this.barChannel.receive(0)); + Message result3c = this.recipientListSubFlow1Result.receive(2000); + assertNotNull(result3c); + assertEquals("BAZ", result3c.getPayload()); + Message result4c = this.recipientListSubFlow2Result.receive(2000); + assertNotNull(result4c); + assertEquals("Hello baz", result4c.getPayload()); this.recipientListInput.send(badMessage); assertNull(this.fooChannel.receive(0)); assertNull(this.barChannel.receive(0)); - Message result3c = this.defaultOutputChannel.receive(2000); - assertNotNull(result3c); - assertEquals("bad", result3c.getPayload()); - + assertNull(this.recipientListSubFlow1Result.receive(0)); + assertNull(this.recipientListSubFlow2Result.receive(0)); + Message resultD = this.defaultOutputChannel.receive(2000); + assertNotNull(resultD); + assertEquals("bad", resultD.getPayload()); } @Test @@ -990,10 +1017,17 @@ public class IntegrationFlowTests { public IntegrationFlow recipientListFlow() { return IntegrationFlows.from("recipientListInput") .transform(p -> p.replaceFirst("Payload", "")) - .routeToRecipients(r -> r.recipient("foo-channel", "'foo' == payload") + .routeToRecipients(r -> r + .recipient("foo-channel", "'foo' == payload") .recipient("bar-channel", m -> m.getHeaders().containsKey("recipient") - && (boolean) m.getHeaders().get("recipient"))) + && (boolean) m.getHeaders().get("recipient")) + .recipientFlow("'foo' == payload or 'bar' == payload or 'baz' == payload", + f -> f.transform(String.class, p -> p.toUpperCase()) + .channel(c -> c.queue("recipientListSubFlow1Result"))) + .recipientFlow(m -> "baz".equals(m.getPayload()), + f -> f.transform("Hello "::concat) + .channel(c -> c.queue("recipientListSubFlow2Result")))) .channel("defaultOutputChannel") .get(); }