shiv
shiv

Reputation: 55

Spring Integration SFTP Exception Handling

I am converting each incoming message to a file and uploading to SFTP server. I get huge exception stack trace logs when SFTP is not available during file upload. This happens every incoming message. Just wondering is there any cleaner solution, where I can catch these exceptions and log a custom message using my CONFIGURED LOGGER ?

   <bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
        <property name="host" value="${ftp.host}"></property>
        <property name="port" value="22" />
        <property name="user" value="${ftp.username}"></property>
        <property name="password" value="${ftp.password}"></property>
        <property name="timeout" value="2000"></property>
    </bean>

    <int:publish-subscribe-channel id="sftpChannel"></int:publish-subscribe-channel>
    <sftp:outbound-channel-adapter id="sftpOutboundAdapter" auto-create-directory="true" session-factory="sftpSessionFactory" channel="sftpChannel" charset="UTF-8" remote-directory="${ftp.path}" remote-filename-generator-expression="headers[fileName] + '.xml'">
        <sftp:request-handler-advice-chain>
            <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
                <property name="onSuccessExpression" value="payload.delete()" />
            </bean>
        </sftp:request-handler-advice-chain>
    </sftp:outbound-channel-adapter>

I have modified the config as below :

<int:publish-subscribe-channel id="sftpChannel"></int:publish-subscribe-channel>
<sftp:outbound-channel-adapter id="sftpOutboundAdapter" auto-create-directory="true" session-factory="sftpSessionFactory" channel="sftpChannel" charset="UTF-8" remote-directory="${spectrum.ftp.path}" remote-filename-generator-expression="headers[fileName] + '.xml'">
    <sftp:request-handler-advice-chain>
        <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="payload.delete()" />
            <property name="failureChannel" ref="errorChannel" />
        </bean>
    </sftp:request-handler-advice-chain>
</sftp:outbound-channel-adapter>

I send this file using :

    outputChannel = context.getBean("sftpChannel", org.springframework.integration.MessageChannel.class);
line#120->     if (outputChannel.send(payload)) {
                        ptsoLog.info("Successfully uploaded file : " + fileName + ".xml");
                    }else{
                        ptsoLog.error("File upload failed : " + e.getMessage());
                    }

but still get this exception :

    org.springframework.integration.MessagingException: Failed to execute on session
        at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:306) ~[spring-integration-file-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:190) ~[spring-integration-file-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:182) ~[spring-integration-file-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.file.remote.handler.FileTransferringMessageHandler.handleMessageInternal(FileTransferringMessageHandler.java:112) ~[spring-integration-file-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_30]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_30]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_30]
        at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_30]
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) ~[spring-aop-3.2.4.RELEASE.jar:3.2.4.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) ~[spring-aop-3.2.4.RELEASE.jar:3.2.4.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[spring-aop-3.2.4.RELEASE.jar:3.2.4.RELEASE]
        at org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice$1.execute(AbstractRequestHandlerAdvice.java:72) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice.doInvoke(ExpressionEvaluatingRequestHandlerAdvice.java:115) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice.invoke(AbstractRequestHandlerAdvice.java:68) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.2.4.RELEASE.jar:3.2.4.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) ~[spring-aop-3.2.4.RELEASE.jar:3.2.4.RELEASE]
        at $Proxy27.handleMessage(Unknown Source) ~[na:na]
        at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:141) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.dispatcher.BroadcastingDispatcher.dispatch(BroadcastingDispatcher.java:123) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:178) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:149) ~[spring-integration-core-3.0.5.RELEASE.jar:na]
        at com.xx.xx.xxx.outputMessage(xxxOutputter.java:120) ~[src/:na]



        Caused by: java.lang.IllegalStateException: failed to create SFTP Session
            at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:321) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
            at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:295) ~[spring-integration-file-3.0.5.RELEASE.jar:na]
            ... 48 common frames omitted
        Caused by: java.lang.IllegalStateException: failed to connect
            at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:250) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
            at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:316) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
            ... 49 common frames omitted
        Caused by: com.jcraft.jsch.JSchException: timeout: socket is not established
            at com.jcraft.jsch.Util.createSocket(Util.java:394) ~[jsch-0.1.51.jar:na]
            at com.jcraft.jsch.Session.connect(Session.java:215) ~[jsch-0.1.51.jar:na]
            at com.jcraft.jsch.Session.connect(Session.java:183) ~[jsch-0.1.51.jar:na]
            at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:241) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
            ... 50 common frames omitted

Caused by: java.lang.IllegalStateException: failed to create SFTP Session
    at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:321) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
    at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:295) ~[spring-integration-file-3.0.5.RELEASE.jar:na]
    ... 47 common frames omitted
Caused by: java.lang.IllegalStateException: failed to connect
    at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:250) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
    at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:316) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
    ... 48 common frames omitted
Caused by: com.jcraft.jsch.JSchException: timeout: socket is not established
    at com.jcraft.jsch.Util.createSocket(Util.java:394) ~[jsch-0.1.51.jar:na]
    at com.jcraft.jsch.Session.connect(Session.java:215) ~[jsch-0.1.51.jar:na]
    at com.jcraft.jsch.Session.connect(Session.java:183) ~[jsch-0.1.51.jar:na]
    at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:241) ~[spring-integration-sftp-3.0.5.RELEASE.jar:na]
    ... 49 common frames omitted

Upvotes: 1

Views: 2975

Answers (1)

Artem Bilan
Artem Bilan

Reputation: 121212

Since you already use ExpressionEvaluatingRequestHandlerAdvice, you can specify the second onFailureExpression option alongside with failureChannel to send an ErrorMessage with the Exception to another channel and do some transformation and logging in that flow.

UPDATE

Thank you for so wide info around an issue.

So, as we see by the StackTrace the ExpressionEvaluatingRequestHandlerAdvice is there too.

And what I can say by source code of it, that it sends an ErrorMessage to the failureChannel only if you specify onFailureExpression. (#root) should be enough for you.

And there is one more option - trapException = true if you want to suppress that exception for rethrowing to the caller.

Upvotes: 1

Related Questions