3

I had to customized Sftp Inbound default handler LoggingHandler and using my own CustomizedErrorHandler which extends ErrorHandler. But I can't return any message to my controller after handling exceptions.

I was researching couple of days and I found nothing to show my customized message to my UI using Controller. Below are some code snippet from my CustomizedErrorHandler, SftpInboundConfiguration.

SftpInboundConfiguration

public IntegrationFlow fileFlow() {
    SftpInboundChannelAdapterSpec spec = Sftp
            .inboundAdapter(getSftpSessionFactory())
            .preserveTimestamp(true)
            .remoteDirectory(getSourceLocation())
            .autoCreateLocalDirectory(true)
            .deleteRemoteFiles(false)
            .localDirectory(new File(getDestinationLocation()));

    return IntegrationFlows
            .from(spec, e -> e.id(BEAN_ID)
                    .autoStartup(false)
                    .poller(sftpPoller())
            )
            .channel(sftpReceiverChannel())
            .handle(sftpInboundMessageHandler())
            .get();
}

... ... ...

public PollerMetadata sftpPoller() {
        PollerMetadata pollerMetadata = new PollerMetadata();
        List<Advice> adviceChain = new ArrayList<>();
        pollerMetadata.setErrorHandler(customErrorMessageHandler());
        pollerMetadata.setTrigger(new PeriodicTrigger(5000));
        return pollerMetadata;
}

... ... ...

private CustomErrorMessageHandler customErrorMessageHandler() {
        return new CustomErrorMessageHandler(
                controlChannel(),
                BEAN_ID
        );
}

CustomErrorMessageHandler

public class CustomErrorMessageHandler implements ErrorHandler {
    private final MessageChannel CONTROL_CHANNEL;
    private final String BEAN_ID;

    public CustomErrorMessageHandler(
                  MessageChannel controlChannel, 
                  String beanID
    ) {
        this.CONTROL_CHANNEL = controlChannel;
        this.BEAN_ID = beanID;
    }

    public void handleError(@NotNull Throwable throwable) {
        final Throwable rootCause = ExceptionUtils.getRootCause(throwable);
        if (rootCause instanceof MessagingException) {
            log.error("MessagingException : {} ", rootCause.getMessage());
        } else if (rootCause instanceof SftpException) {
            log.error("SftpException : {}", rootCause.getMessage());
        }   ... ... ... 
        else {
            log.error("Unknown : Cause : {} , Error : {}", 
                                 rootCause, rootCause.getMessage());
        }


        log.info("Stopping SFTP Inbound");
        boolean is_stopped = CONTROL_CHANNEL.send(
                 new GenericMessage<>("@" + BEAN_ID + ".stop()"));
        if (is_stopped) {
            log.info("SFTP Inbound Stopped.");
        } else {
            log.info("SFTP Inbound Stop Failed.");
        }
    }
}

Now I want to save some customized message from if-else statements and need to show it in UI. Is there any way to save the message and show it using Route or Controller ?

Towfiqul Islam
  • 456
  • 6
  • 14

1 Answers1

2

Don't customize the error handler, use poller.errorChannel("myErrorChannel") instead.

Then add an error channel flow

@Bean
IntegrationFlow errors() {
    return IntegrationFLows.from("myErrorChannel")
        .handle(...)
        ...
        .get();

The message sent to the handler is an ErrorMessage with a MessagingException payload, with cause and failedMessage which was the message at the point of the failure and originalMessage which is the original message emitted by the adapter.

After handling the exception, you can simply call a method on your controller to tell it the state.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • I couldn't understand `poller.errorChannel(...)` . Can you please give an example ? I am getting only `poller.setErrorHandler(...)` in my **`PollerMetadata`** – Towfiqul Islam Jun 02 '20 at 22:01
  • 1
    instead of `.poller(sftpPoller())` use `.poller(Pollers.fixedDelay(5000).errorChannel("myErrors")`). – Gary Russell Jun 02 '20 at 22:05
  • 1
    The `PollerSpec` has `advice(Advice... advices)`. https://docs.spring.io/spring-integration/api/org/springframework/integration/dsl/PollerSpec.html – Gary Russell Jun 02 '20 at 22:18
  • sorry for asking the previous question. It was my typing mistake that I was making in my code. Thank you so much for your answer and comments. I will comment again If I stuck to any other issues. – Towfiqul Islam Jun 02 '20 at 22:21
  • 1
    You can use `.handle(controller, "setState")` to send a message containing state to your controller. – Gary Russell Jun 02 '20 at 22:35
  • Thank you for your answer and suggestion. Specially the last comment is very interesting. :D – Towfiqul Islam Jun 03 '20 at 01:09