I am trying to rewrite Spring Integration flow from XML to Java. I would like to route data sent over a channel:
@Bean(name = "sendData")
public MessageChannel getSendData() {
return MessageChannels.direct()
.get();
}
into two other channels:
@Bean(name = "sendDataA")
public MessageChannel getSendDataA() {
return MessageChannels.direct()
.get();
}
@Bean(name = "sendDataB")
public MessageChannel getSendDataB() {
return MessageChannels.direct()
.get();
}
depending on their availability.
I have a RoundRobinRouter
class that determines which output channel to use. It has a method route
that returns output channel name, like:
@Component
class RoundRobinRouter {
public String route(Object payload) {
/* implementation */
}
}
Note that route
method implementation does not actually use the payload
object. It was previously placed in XML configuration:
<int:router method="route" input-channel="sendData"
default-output-channel="sendDataA">
<bean
class="com.example.RoundRobinRouter"/>
</int:router>
I have already tried using Java DSL IntegrationFlow
:
@Bean
@ServiceActivator(inputChannel = "sendData",
outputChannel = "sendDataA")
public IntegrationFlow routeRoundRobin() {
return router -> router.route(roundRobinRouter, "route");
}
But I was getting an error "Dispatcher has no subscribers" on sendData.send(payload)
call, apparently caused by:
org.springframework.expression.spel.SpelEvaluationException: EL1004E:(pos 8): Method call: Method configure(com.example.DataType) cannot be found on com.example.Integration$$Lambda$1/1018103616 type
The router is the only lambda in my Integration class.
Okay, I got it to work. I'm not sure which change fixed my problem, but here's correct router implementation:
@Bean
public IntegrationFlow routeRoundRobin() {
return IntegrationFlows.from(getSendData())
.route(roundRobinRouter, "route",
r -> r.channelMapping("sendDataA",
"sendDataA")
.channelMapping("sendDataB",
"sendDataB"))
.get();
}
@Bean(name = "sendData")
public MessageChannel getSendData() {
return MessageChannels.direct()
.get();
}
@Bean(name = "sendDataA")
public MessageChannel getSendDataA() {
return MessageChannels.direct()
.get();
}
@Bean(name = "sendDataB")
public MessageChannel getSendDataB() {
return MessageChannels.direct()
.get();
}
I changed @ServiceActivator
to IntegrationFlow
from sendData
, and also added channel mapping to the router.