Secure data sending with sftp and spring batch

It is possible to send data with spring batch in several ways. The most used case is sending XML files, but the spring framework offers you a lot of other ways too. One of these ways is to send your data files secure by using SFTP. For this use case you can use the spring integration framework.

Firstly we need a SftpSesstionFactory for sending the files to a sftp server. This factory includes the properties for access to the server.

<bean id="sftpSessionFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
  <property name="host" value="host.of.receiver"/>
  <property name="user" value="username"/>
  <property name="password" value="secureSftpPassword"/>
  <property name="port" value="22"/>
</bean>

Afterwards we need a channel. This channel is used to send the data.

<int:channel id="outputChannel" />

Now we have to link the channel to the SftpSessionFactory. For this we use an outbound-channel-adapter, which includes the channel, the sessionFactory and tells the framework how the file should be named on the target server (remote-filename-generator).

<int-sftp:outbound-channel-adapter id="sftpOutboundAdapter"
  session-factory="sftpSessionFactory"
  channel="outputChannel"
  charset="UTF-8"
  remote-directory="/target"
  remote-filename-generator="fileNameGenerator" />

To make it easy for us, the target server should store the file with the same name like the sending file was named. For this we can use the DefaultFileNameGenerator of spring integration.

<bean id="fileNameGenerator" class="org.springframework.integration.file.DefaultFileNameGenerator" />

Now we really want to send the file. For this we need a tasklet with the bussiness logic and at least the batch job.
For the tasklet we need a small java class with the filename as parameter.

The Tasklet:

<bean id="sftpJobTasklet" class="de.package.tasklets.SftpTasklet">
  <property name="fileName" value=" path/to/file/filename.csv" />
  <property name="sftpChannel" ref="outputChannel" />
</bean>

The Javacode:

package de.package.tasklets;
 
import java.io.File;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.support.MessageBuilder;
 
public class SftpTasklet implements Tasklet {
 
  private String fileName;
  private MessageChannel sftpChannel;
 
  @Override
  public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
 
    File file = new File(fileName);
    if (file.exists()) {
      Message message = MessageBuilder.withPayload(file).build();
      try {
        sftpChannel.send(message);
      } catch (Exception e) {
        System.out.println("Could not send file per SFTP: " + e);
      }
    } else {
      System.out.println("File does not exist.");
    }
    return RepeatStatus.FINISHED;
  }
 
  public String getFileName() {
    return fileName;
  }
 
  public void setFileName(String fileName) {
    this.fileName = fileName;
  }
 
  public MessageChannel getSftpChannel() {
    return this.sftpChannel;
  }
 
  public void setSftpChannel(MessageChannel sftpChannel) {
    this.sftpChannel = sftpChannel;
  }
}

And now, at least, the xml code for the batch job:

<batch:job id="sftpJob" restartable="false">
  <batch:step id="sftpFileSendStep">
    <batch:tasklet ref="sftpJobTasklet" />
  </batch:step>
</batch:job>

This batch job can be started by a cron job on the server.

At last part I will shortly post the header of the xml file called applicationContext.xml, which includes all the described beans:

<?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:batch="http://www.springframework.org/schema/batch"
  xmlns:int="http://www.springframework.org/schema/integration"
  xmlns:int-file="http://www.springframework.org/schema/integration/file"
  xmlns:int-sftp="http://www.springframework.org/schema/integration/sftp"
  xmlns:int-stream="http://www.springframework.org/schema/integration/stream"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
  http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
  http://www.springframework.org/schema/integration/file http://www.springframework.org/schema/integration/file/spring-integration-file-2.0.xsd
  http://www.springframework.org/schema/integration/sftp http://www.springframework.org/schema/integration/sftp/spring-integration-sftp-2.0.xsd
  http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream-2.0.xsd">
Print Friendly, PDF & Email

Leave a Comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*
*