3

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

Menno
  • 97
  • 1
  • 7

1 Answers1

1

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.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Hi Artem, thanks for your detailed answer. Is it not possible to add a way to specify a service interface on the GatewayEndpointSpec, so that the recently added .gateway() EIP method could then be used to set up the gateway and corresponding service interface? – Menno Sep 11 '14 at 12:48
  • No, because `.gateway()` plays the same role as `` within `` and it is a middle of flow. When `@MessagingGateway` is a POJI bridge from your code to the Spring Integration Flow using just method invocation and DI. Don't mix concerns. Anyway you need a `method invocation` from the Batch step listener. So any changes to the `.gateway()` won't help you, because exactly your Batch Job starts the flow invocing method on interface. – Artem Bilan Sep 11 '14 at 12:56