3
votes

I am trying to configure a Spring Batch listener to send a message to a Spring Integration Gateway for StepExecution events.

The following link explains how to configure this with XML

http://docs.spring.io/spring-batch/trunk/reference/html/springBatchIntegration.html#providing-feedback-with-informational-messages

How can this be setup using Spring Integration DSL? I've found no way to configure a gateway with a service interface using DSL.

At the moment I worked around this by implementing an actual StepExecutionListener, and have this then calling an interface which is annotated with @MessagingGateway (calling the corresponding @Gateway method) in order to get a message to a channel. And I then setup an Integration DSL flow for this channel.

Is there a simpler way using DSL, avoiding that workaround? Is there some way to connect a Batch listener direct to a gateway, like one can using XML config?

Cheers, Menno

1

1 Answers

1
votes

First of all SI DSL is just an extension of existing SI Java and Annotation configuration, so it can be used together with any other Java config. Of course an XML @Import is also posible.

There is no gateway configuration in the DSL, because its methods can't be wired with linear IntegrationFlow. There is need to provide downstream flows for each method.

So, @MessagingGateway is a right way to go ahead:

@MessagingGateway(name = "notificationExecutionsListener", defaultRequestChannel = "stepExecutionsChannel")
public interface MyStepExecutionListener extends StepExecutionListener {}

From other side @MessagingGateway parsing as well as <gateway> tag parsing ends up with GatewayProxyFactoryBean definition. So, you just can declare that bean, if you don't want to introduce a new class:

@Bean
public GatewayProxyFactoryBean notificationExecutionsListener(MessageChannel stepExecutionsChannel) {
    GatewayProxyFactoryBean gateway = new GatewayProxyFactoryBean(StepExecutionListener.class);
    gateway.setDefaultRequestChannel(stepExecutionsChannel);
    return gateway;
}

After the latest Milestone 3 I have an idea to introduce nested flows, when we may be able to introduce Gateway support for flows. Something like this:

@Bean
public IntegrationFlow gatewayFlow() {
        return IntegrationFlows
               .from(MyGateway.class, g -> 
                                         g.method("save", f -> f.transform(...)
                                                                .filter(...))
                                          .method("delete", f -> f.handle(...)))
               .handle(...)
               .get();                            
}

However I'm not sure that it will simplify the life, as far as any nested Lambda just adds more noise and might break loosely coupling principle.