Daten sicher versenden mit SFTP und Spring Batch

Datenversand mit spring batch in auf viele Weisen möglich. Der bekannteste Weg ist der Versand von XML-Dateien aber das Springframework bietet auch eine Menge anderer Möglichkeiten an. Einer Dieser Wege ist der sichere Datenversand über SFTP. Für diesen Fall müssen wir das Spring integration Framework verwenden.

Als erstes benötigen wir eine SftpSessionFactory für den Versand der Dateien an den SFTP-Server. Diese Factory beinhaltet die Zugangsdaten zum 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>

Dann brauchen wir einen Channel, über den die Daten gesendet werden können.

<int:channel id="outputChannel" />

Als nächstes müssen wir den Channel mit der SftpSessionFactory verlinken. Hierfür verwenden wir einen sogenannten outbound-channel-adapter, welcher den Channel und die SftpSessionFactory beinhaltet und dem Framework mitteilt, mit welchem Namen die Datei auf dem zielserver gespeichert werden soll (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" />

Um es uns einfach zu machen, sagen wir einfach einmal, die Datei soll unter dem selben Namen wie auf dem sendenden Server gespeichert werden, denn dann können wir den DefaultFileNameGenerator vom Spring integration Framework verwenden.

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

Jetzt möchten wir die Datei aber wirklich senden. Hierfür benötigen wir ein Tasklet für die Bussiness Logik und zu guter Letzt einen BatchJob.
Für das Tasklet verwenden wir folgende Java Klasse und Bean, der wir den Dateinamen als Parameter mitgeben:

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;
  }
}

Und nun, zu guter Letzt, der XML-Code für den BatchJob:

<batch:job id="sftpJob" restartable="false">
  <batch:step id="sftpFileGenerateStep" next="sftpFileSendStep">
    <batch:tasklet>
      <batch:chunk reader="sftpFileCreator" writer="sftpFileWriter" commit-interval="100" />
      <batch:listeners>
        <batch:listener ref="fileNameListener" />
      </batch:listeners>
    </batch:tasklet>
  </batch:step>
  <batch:step id="sftpFileSendStep">
    <batch:tasklet ref="sftpJobTasklet" />
  </batch:step>
</batch:job>

dieser BatchJob kann nun durch einen CronJob auf dem Server gestartet werden.

Zum Abschluß noch der Header der XML-Datei (applicationContext.xml), welche die beschriebenen Beans beinhaltet:

<?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.

*
*