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 без send() Citrus для выполнения таких задач?


person Andy Longwill    schedule 21.04.2017    source источник


Ответы (1)


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

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

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

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

person Artem Bilan    schedule 21.04.2017