Citrus Framework - загрузка файла через SFTP с использованием Spring Integration

В рамках теста Citrus я хотел бы отправить файл CSV на сервер через SFTP. Кажется, это должно быть возможно с помощью Spring Integration. Я попытался использовать код ниже:

цитрус-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:citrus="http://www.citrusframework.org/schema/config"
       xmlns:citrus-test="http://www.citrusframework.org/schema/testcase"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp.xsd
       http://www.citrusframework.org/schema/config http://www.citrusframework.org/schema/config/citrus-config.xsd
       http://www.citrusframework.org/schema/testcase http://www.citrusframework.org/schema/testcase/citrus-testcase.xsd
">

    <!-- Common settings -->
    <context:property-placeholder location="classpath:citrus.properties"/>

    <citrus:schema-repository id="schemaRepository"/>   

    <!-- SFTP component -->
    <bean id="sftpSessionFactory" class="org.springframework.integration.file.remote.session.CachingSessionFactory">
        <constructor-arg ref="defaultSftpSessionFactory" />
    </bean>

    <bean id="defaultSftpSessionFactory"
          class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
        <property name="host" value="${sftp.host}"/>
        <property name="privateKey" value="${sftp.private.keyfile}"/>
        <property name="port" value="${sftp.port}"/>
        <property name="user" value="${sftp.username}"/>
        <property name="allowUnknownKeys" value="true"/>
    </bean>

    <int-sftp:outbound-channel-adapter id="sftpOutboundAdapter"
                                       session-factory="sftpSessionFactory"
                                       channel="inputChannel"
                                       remote-filename-generator-expression="payload.getName()"
                                       remote-directory="/tmp/citrus">
        <int-sftp:request-handler-advice-chain>
            <int:retry-advice />
        </int-sftp:request-handler-advice-chain>
    </int-sftp:outbound-channel-adapter>

    <int:channel id="inputChannel"/>

    <citrus:channel-endpoint id="sftpEndpoint" channel="inputChannel" />
</beans>

SftpTransferIT.java

public class SftpTransferIT extends TestNGCitrusTestDesigner {

    @Autowired
    ChannelEndpoint sftpEndpoint;

    @Test @Parameters("context")
    @CitrusTest(name = "SftpTransferIT.sendFileByFTP")
    public void sendFileByFTP(@Optional @CitrusResource TestContext context) {

        final File file = new File("C:\\Temp\\example.xml");
        final org.springframework.messaging.Message<File> message = MessageBuilder.withPayload(file).build();
        Message ftpMessage = new ChannelMessageConverter().convertInbound(message,sftpEndpoint.getEndpointConfiguration(),context);

        send(sftpEndpoint).message(ftpMessage);

    }
}

В этой ситуации выдается следующее исключение:

Caused by: org.springframework.messaging.MessagingException: Failed to write to '/tmp/citrus/example.xml.writing' while uploading the file; nested exception is org.springframework.core.NestedIOException: failed to write file; nested exception is 2: No such file
    at org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:537)
    at org.springframework.integration.file.remote.RemoteFileTemplate.lambda$send$0(RemoteFileTemplate.java:310)
    ... 69 more
Caused by: org.springframework.core.NestedIOException: failed to write file; nested exception is 2: No such file
    at org.springframework.integration.sftp.session.SftpSession.write(SftpSession.java:158)
    at org.springframework.integration.file.remote.session.CachingSessionFactory$CachedSession.write(CachingSessionFactory.java:228)
    at org.springframework.integration.file.remote.RemoteFileTemplate.sendFileToRemoteDirectory(RemoteFileTemplate.java:509)
    ... 70 more
Caused by: 2: No such file
    at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2873)

Я думаю, что ошибка в том, как я отправляю сообщение через Citrus. Кто-то может посоветовать, пожалуйста, как правильно отправить сообщение org.springframework.messaging.Message через Citrus?

Или лучше использовать чистую Spring Integration без функции send() Citrus для выполнения подобных задач?

1 ответ

Попробуйте настроить use-temporary-file-name = "false":

По умолчанию каждый файл, который находится в процессе передачи, будет отображаться в файловой системе с дополнительным суффиксом, который по умолчанию является.writing; это можно изменить с помощью атрибута временного файла-суффикса.

Однако могут быть ситуации, когда вы не хотите использовать эту технику (например, если сервер не разрешает переименовывать файлы). В подобных ситуациях вы можете отключить эту функцию, установив для use-orary-file-name значение false (по умолчанию установлено значение true). Когда этот атрибут имеет значение false, файл записывается с его окончательным именем, и приложению-потребителю потребуется какой-то другой механизм, чтобы определить, что файл полностью загружен, прежде чем получить к нему доступ.

И будь уверен, что /tmp/citrus действительно существует на вашем SFTP.

Другие вопросы по тегам