3

I don't know if this question is about spring-integration, spring-integration-dsl or both, so I just added the 2 tags...

I spend a considerable amount of time today, first doing a simple flow with a filter

StandardIntegrationFlow flow = IntegrationFlows.from(...)
                    .filter(messagingFilter)
                    .transform(transformer)
                    .handle((m) -> {
                        (...)
                    })
                    .get();

The messagingFilter being a very simple implementation of a MessageSelector. So far so good, no much time spent. But then I wanted to log a message in case the MessageSelector returned false, and here is where I got stuck.

After quite some time I ended up with this:

StandardIntegrationFlow flow = IntegrationFlows.from(...)
                    .filter(messagingFilters, fs -> fs.discardFlow( i -> i.channel(discardChannel()))
                    .transform(transformer)
                    .handle((m) -> {
                        (...)
                    })
                    .get();

(...)

public MessageChannel discardChannel() {
    MessageChannel channel = new MessageChannel(){
        @Override
        public boolean send(Message<?> message) {
            log.warn((String) message.getPayload().get("msg-failure"));
            return true;
        }
        @Override
        public boolean send(Message<?> message, long timeout) {
            return this.send(message);
        }
    };
    return channel;
}

This is both ugly and verbose, so the question is, what have I done wrong here and how should I have done it in a better, cleaner, more elegant solution?

Cheers.

amsmota
  • 171
  • 2
  • 11

1 Answers1

3

Your problem that you don't see that Filter is a EI Pattern implementation and the maximum it can do is to send discarded message to some channel. It isn't going to log anything because that approach won't be Messaging-based already.

The simplest way you need for your use-case is like:

.discardFlow(df -> df
        .handle(message -> log.warn((String) message.getPayload().get("msg-failure")))))

That your logic to just log. Some other people might do more complicated logic. So, eventually you'll get to used to with channel abstraction between endpoints.

I agree that new MessageChannel() {} approach is wrong. The logging indeed should be done in the MessageHandler instead. That is the level of the service responsibility. Also don't forget that there is LoggingHandler, which via Java DSL can be achieved as:

 .filter(messagingFilters, fs -> fs.discardFlow( i -> i.log(message -> (String) message.getPayload().get("msg-failure"))))
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118