Java Spring集成| DSL

Java Spring集成| DSL,java,spring,spring-integration,spring-dsl,Java,Spring,Spring Integration,Spring Dsl,我正在尝试向远程SFTP服务器发送文件。我已经创建了一个工厂和一个outboundFlow 上传者FTPConnectionFactoryBuilder @配置 公共类上载器FTPConnectionFactoryBuilder{ @值(${report uploader.sftp factory.host}”) 私有字符串主机=null; @值(${report uploader.sftp factory.port}”) 专用整数端口=null; @值(“类路径:${report upload

我正在尝试向远程SFTP服务器发送文件。我已经创建了一个工厂和一个outboundFlow

上传者FTPConnectionFactoryBuilder
@配置
公共类上载器FTPConnectionFactoryBuilder{
@值(${report uploader.sftp factory.host}”)
私有字符串主机=null;
@值(${report uploader.sftp factory.port}”)
专用整数端口=null;
@值(“类路径:${report uploader.sftp factory.privateKey}”)
私有资源privateKey=null;
@值(${report uploader.sftp factory.privateKeyPassphrase}”)
私有字符串privateKeyPassphrase=null;
@值(${report uploader.sftp factory.maxConnections}”)
私有字符串maxConnections=null;
@值(${report uploader.sftp factory.user}”)
私有字符串user=null;
@值(${report uploader.sftp factory.poolSize}”)
私有整数poolSize=null;
@值(${report uploader.sftp factory.sessionWaitTimeout}”)
private Long sessionWaitTimeout=null;
//@Bean(name=“cachedSftpSessionFactory”)
public DefaultSftpSessionFactory getSftpSessionFactory(){
DefaultSftpSessionFactory DefaultSftpSessionFactory=新的DefaultSftpSessionFactory();
可选.ofNullable(this.getHost()).ifPresent(值->defaultSftpSessionFactory.setHost(值));
可选.ofNullable(this.getPort()).ifPresent(value->defaultSftpSessionFactory.setPort(port));
可选.ofNullable(this.getPrivateKey()).ifPresent(
value->defaultSftpSessionFactory.setPrivateKey(privateKey));
可选.ofNullable(this.getPrivateKeyPassphrase()).ifPresent(
value->defaultSftpSessionFactory.setPrivateKeyPassphrase(value));
可选.ofNullable(this.getUser()).ifPresent(value->defaultSftpSessionFactory.setUser(value));
返回工厂;
}
@Bean(name=“cachedSftpSessionFactory”)
public CachingSessionFactory getCachedSftpSessionFactory(){
CachingSessionFactory cachedFtpSessionFactory=新建CachingSessionFactory(
getSftpSessionFactory());
setPoolSize(poolSize);
cachedFtpSessionFactory.setSessionWaitTimeout(sessionWaitTimeout);
返回工厂;
}
公共字符串getHost(){
返回主机;
}
公共void setHost(字符串主机){
this.host=host;
}
公共资源getPrivateKey(){
返回私钥;
}
public void setPrivateKey(资源privateKey){
this.privateKey=privateKey;
}
公共字符串getPrivateKeyPassphrase(){
返回privateKeyPassphrase;
}
public void setPrivateKeyPassphrase(字符串privateKeyPassphrase){
this.privateKeyPassphrase=privateKeyPassphrase;
}
公共字符串getMaxConnections(){
返回maxConnections;
}
公共void setMaxConnections(字符串maxConnections){
this.maxConnections=maxConnections;
}
公共整数getPort(){
返回端口;
}
公共无效设置端口(整数端口){
this.port=端口;
}
公共字符串getUser(){
返回用户;
}
公共void setUser(字符串用户){
this.user=用户;
}
}

现在我想使用集成测试来测试出站流。为此,我创建了以下testContext:

TestContextConfiguration
@配置
公共类TestContextConfiguration{
@配置
@导入({FakeSftpServer.class,JmxAutoConfiguration.class,IntegrationAutoConfiguration.class,
UploaderSftpConnectionFactoryBuilder.class})
@集成组件扫描
公共静态类上下文配置{
@值(${report uploader.reportingServer.fileEncoding}”)
私有字符串文件编码;
@自动连线
私有FakeSftpServer FakeSftpServer;
@自动连线
@限定符(“cachedSftpSessionFactory”)
//CachingSessionFactory cachedSftpSessionFactory;
DefaultSftpSessionFactory缓存FtpSessionFactory;
@豆子
公共集成流sftpOutboundFlow(){
返回积分流
.从(“toSftpChannel”)
.handle(Sftp.outboundAdapter(this.cachedSftpSessionFactory,FileExistsMode.REPLACE)
.charset(charset.forName(fileEncoding)).remoteFileSeparator(“\\”)
.remoteDirectory(此.fakeSftpServer.getTargetSftpDirectory().getPath())
.fileNameExpression(“payload.getName()”).autoCreateDirectory(true)
.useTemporaryFileName(true).temporaryFileSuffix(“.Transferring”)
).get();
}
@豆子
公共静态属性资源占位符配置器属性资源占位符配置器(){
返回新属性资源占位符配置器();
}
}
我还按照建议创建了一个假的sftp服务器@ 下面是我的假服务器:

FakeSftpServer
@配置(“fakeSftpServer”)
公共类FakeSftpServer实现初始化bean,DisposableBean{
私有最终SshServer服务器=SshServer.setUpDefaultServer();
private final int port=SocketUtils.findAvailableTcpPort();
私人最终临时文件夹;
私有最终临时文件夹localFolder;
私有易失性文件;
私有易失性文件源sftpdirectory;
私有易失性文件targetSftpDirectory;
私有易失性文件sourceLocalDirectory;
私有易失性文件targetLocalDirectory;
公共FakeSftpServer(){
this.sftpFolder=新建临时文件夹(){
@凌驾
public void create()引发IOException{
super.create();
sftpRootFolder=this.newFolder(“sftpTest”);
targetSftpDirectory=新文件(sftpRootFolder,“sftpTarget”);
targetSftpDirectory.mkdir();
}
};
this.localFolder=新建临时文件夹(){
@凌驾
public void create()引发IOException{
super.create();
File rootFolder=this.newFolder(“sftpTest”);
@Configuration
public class UploaderSftpConnectionFactoryBuilder {

@Value("${report-uploader.sftp-factory.host}")
private String host = null;
@Value("${report-uploader.sftp-factory.port}")
private Integer port = null;
@Value("classpath:${report-uploader.sftp-factory.privateKey}")
private Resource privateKey = null;
@Value("${report-uploader.sftp-factory.privateKeyPassphrase}")
private String privateKeyPassphrase = null;
@Value("${report-uploader.sftp-factory.maxConnections}")
private String maxConnections = null;
@Value("${report-uploader.sftp-factory.user}")
private String user = null;
@Value("${report-uploader.sftp-factory.poolSize}")
private Integer poolSize = null;
@Value("${report-uploader.sftp-factory.sessionWaitTimeout}")
private Long sessionWaitTimeout = null;

//@Bean(name = "cachedSftpSessionFactory")
public DefaultSftpSessionFactory getSftpSessionFactory() {
    DefaultSftpSessionFactory defaultSftpSessionFactory = new DefaultSftpSessionFactory();

    Optional.ofNullable(this.getHost()).ifPresent(value -> defaultSftpSessionFactory.setHost(value));
    Optional.ofNullable(this.getPort()).ifPresent(value -> defaultSftpSessionFactory.setPort(port));
    Optional.ofNullable(this.getPrivateKey()).ifPresent(
            value -> defaultSftpSessionFactory.setPrivateKey(privateKey));
    Optional.ofNullable(this.getPrivateKeyPassphrase()).ifPresent(
            value -> defaultSftpSessionFactory.setPrivateKeyPassphrase(value));
    Optional.ofNullable(this.getUser()).ifPresent(value -> defaultSftpSessionFactory.setUser(value));

    return defaultSftpSessionFactory;
}

@Bean(name = "cachedSftpSessionFactory")
public CachingSessionFactory<LsEntry> getCachedSftpSessionFactory() {
    CachingSessionFactory<LsEntry> cachedFtpSessionFactory = new CachingSessionFactory<LsEntry>(
            getSftpSessionFactory());
    cachedFtpSessionFactory.setPoolSize(poolSize);
    cachedFtpSessionFactory.setSessionWaitTimeout(sessionWaitTimeout);
    return cachedFtpSessionFactory;
}

public String getHost() {
    return host;
}

public void setHost(String host) {
    this.host = host;
}

public Resource getPrivateKey() {
    return privateKey;
}

public void setPrivateKey(Resource privateKey) {
    this.privateKey = privateKey;
}

public String getPrivateKeyPassphrase() {
    return privateKeyPassphrase;
}

public void setPrivateKeyPassphrase(String privateKeyPassphrase) {
    this.privateKeyPassphrase = privateKeyPassphrase;
}

public String getMaxConnections() {
    return maxConnections;
}

public void setMaxConnections(String maxConnections) {
    this.maxConnections = maxConnections;
}

public Integer getPort() {
    return port;
}

public void setPort(Integer port) {
    this.port = port;
}

public String getUser() {
    return user;
}

public void setUser(String user) {
    this.user = user;
}
@Configuration
public class TestContextConfiguration {
@Configuration
@Import({ FakeSftpServer.class, JmxAutoConfiguration.class, IntegrationAutoConfiguration.class,
        UploaderSftpConnectionFactoryBuilder.class })
@IntegrationComponentScan
public static class ContextConfiguration {

    @Value("${report-uploader.reportingServer.fileEncoding}")
    private String fileEncoding;

    @Autowired
    private FakeSftpServer fakeSftpServer;

    @Autowired
    @Qualifier("cachedSftpSessionFactory")
    //CachingSessionFactory<LsEntry> cachedSftpSessionFactory;
    DefaultSftpSessionFactory cachedSftpSessionFactory;

    @Bean
    public IntegrationFlow sftpOutboundFlow() {
        return IntegrationFlows
                .from("toSftpChannel")
                .handle(Sftp.outboundAdapter(this.cachedSftpSessionFactory, FileExistsMode.REPLACE)
                        .charset(Charset.forName(fileEncoding)).remoteFileSeparator("\\")
                        .remoteDirectory(this.fakeSftpServer.getTargetSftpDirectory().getPath())
                        .fileNameExpression("payload.getName()").autoCreateDirectory(true)
                        .useTemporaryFileName(true).temporaryFileSuffix(".tranferring")
                        ).get();
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

}
@Configuration("fakeSftpServer")
public class FakeSftpServer implements InitializingBean, DisposableBean {

    private final SshServer server = SshServer.setUpDefaultServer();

    private final int port = SocketUtils.findAvailableTcpPort();

    private final TemporaryFolder sftpFolder;

    private final TemporaryFolder localFolder;

    private volatile File sftpRootFolder;

    private volatile File sourceSftpDirectory;

    private volatile File targetSftpDirectory;

    private volatile File sourceLocalDirectory;

    private volatile File targetLocalDirectory;

    public FakeSftpServer() {
            this.sftpFolder = new TemporaryFolder() {

                    @Override
                    public void create() throws IOException {
                            super.create();
                            sftpRootFolder = this.newFolder("sftpTest");
                            targetSftpDirectory = new File(sftpRootFolder, "sftpTarget");
                            targetSftpDirectory.mkdir();
                    }
            };

            this.localFolder = new TemporaryFolder() {

                    @Override
                    public void create() throws IOException {
                            super.create();
                            File rootFolder = this.newFolder("sftpTest");
                            sourceLocalDirectory = new File(rootFolder, "localSource");
                            sourceLocalDirectory.mkdirs();
                            File file = new File(sourceLocalDirectory, "localSource1.txt");
                            file.createNewFile();
                            file = new File(sourceLocalDirectory, "localSource2.txt");
                            file.createNewFile();

                            File subSourceLocalDirectory = new File(sourceLocalDirectory, "subLocalSource");
                            subSourceLocalDirectory.mkdir();
                            file = new File(subSourceLocalDirectory, "subLocalSource1.txt");
                            file.createNewFile();

                    }
            };
    }

    @Override
    public void afterPropertiesSet() throws Exception {
            this.sftpFolder.create();
            this.localFolder.create();

            this.server.setPasswordAuthenticator((username, password, session) -> true);
            this.server.setPort(this.port);
            this.server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(new File("src/test/resources/hostkey.ser")));
            this.server.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
            this.server.setFileSystemFactory(new VirtualFileSystemFactory(sftpRootFolder.toPath()));
            this.server.start();
    }

    @Override
    public void destroy() throws Exception {
            this.server.stop();
            this.sftpFolder.delete();
            this.localFolder.delete();
    }

    public File getSourceLocalDirectory() {
            return this.sourceLocalDirectory;
    }

    public File getTargetLocalDirectory() {
            return this.targetLocalDirectory;
    }

    public String getTargetLocalDirectoryName() {
            return this.targetLocalDirectory.getAbsolutePath() + File.separator;
    }

    public File getTargetSftpDirectory() {
            return this.targetSftpDirectory;
    }

    public void recursiveDelete(File file) {
            File[] files = file.listFiles();
            if (files != null) {
                    for (File each : files) {
                            recursiveDelete(each);
                    }
            }
            if (!(file.equals(this.targetSftpDirectory) || file.equals(this.targetLocalDirectory))) {
                    file.delete();
            }
    }
}
@ContextConfiguration(classes = { TestContextConfiguration.class }, initializers = {ConfigFileApplicationContextInitializer.class})
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class TestConnectionFactory {

@Autowired
@Qualifier("cachedSftpSessionFactory")
CachingSessionFactory<LsEntry> cachedSftpSessionFactory;
//DefaultSftpSessionFactory cachedSftpSessionFactory;

@Autowired
FakeSftpServer fakeSftpServer;

@Autowired
@Qualifier("toSftpChannel")
private MessageChannel toSftpChannel;

@After
public void setupRemoteFileServers() {
        this.fakeSftpServer.recursiveDelete(this.fakeSftpServer.getSourceLocalDirectory());
        this.fakeSftpServer.recursiveDelete(this.fakeSftpServer.getTargetSftpDirectory());
}

@Test
public void testSftpOutboundFlow() {
        boolean status = this.toSftpChannel.send(MessageBuilder.withPayload(new File(this.fakeSftpServer.getSourceLocalDirectory() + "\\" + "localSource1.txt")).build());

        RemoteFileTemplate<ChannelSftp.LsEntry> template = new RemoteFileTemplate<>(this.cachedSftpSessionFactory);
        ChannelSftp.LsEntry[] files = template.execute(session ->
                        session.list(this.fakeSftpServer.getTargetSftpDirectory() + "\\" + "localSource1.txt"));
        assertEquals(1, files.length);
        //assertEquals(3, files[0].getAttrs().getSize());
    }
}
org.springframework.messaging.MessagingException: ; nested exception is org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is java.lang.IllegalStateException: failed to create SFTP Session
at org.springframework.integration.dispatcher.AbstractDispatcher.wrapExceptionIfNecessary(AbstractDispatcher.java:133)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:120)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:286)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:245)
at com.sapient.lufthansa.reportuploader.config.TestConnectionFactory.testSftpOutboundFlow(TestConnectionFactory.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:224)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.springframework.messaging.MessagingException: Failed to execute on session; nested exception is java.lang.IllegalStateException: failed to create SFTP Session
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:345)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:211)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:201)
at org.springframework.integration.file.remote.RemoteFileTemplate.send(RemoteFileTemplate.java:193)
at org.springframework.integration.file.remote.handler.FileTransferringMessageHandler.handleMessageInternal(FileTransferringMessageHandler.java:110)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
... 36 more
Caused by: java.lang.IllegalStateException: failed to create SFTP Session
at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:355)
at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:49)
at org.springframework.integration.file.remote.RemoteFileTemplate.execute(RemoteFileTemplate.java:334)
... 42 more
Caused by: java.lang.IllegalStateException: failed to connect
at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:272)
at org.springframework.integration.sftp.session.DefaultSftpSessionFactory.getSession(DefaultSftpSessionFactory.java:350)
... 44 more
Caused by: com.jcraft.jsch.JSchException: java.net.ConnectException: Connection refused: connect
at com.jcraft.jsch.Util.createSocket(Util.java:349)
at com.jcraft.jsch.Session.connect(Session.java:215)
at com.jcraft.jsch.Session.connect(Session.java:183)
at org.springframework.integration.sftp.session.SftpSession.connect(SftpSession.java:263)
... 45 more
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at com.jcraft.jsch.Util.createSocket(Util.java:343)
... 48 more