0
votes

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.

1

1 Answers

0
votes

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.