SAP: FTP-Verbindungen in ABAP

Auf einem SAP-System kann man eine FTP-Datenübertragung direkt in ABAP durchführen. Der Funktionsbaustein zum Aufbau der FTP-Verbindung ist FTP_CONNECT. Die Übergabe des FTP-Passworts ist nicht intuitiv. Wenn vorhanden, ist ein FTP-Transfer mit Hilfe eines SAP-PO in der Regel vorzuziehen!

Bitte zuerst die Alternative eines PO-Systems prüfen!

Auch wenn man FTP-Transfers direkt in ABAP durchführen kann, ist es fast immer besser, hierfür ein SAP-PO-System zu verwenden. SAP PO ist ein eigenes System, das auf Datenübertragung mit einer großen Zahl von Übertragungsprotokollen ausgerichtet ist, darunter auch FTP, SFTP, REST, Json, etc. In vielen Unternehmen steht ein begleitendes PO-System ohnehin zur Verfügung. Dann ist es üblicherweise die bessere Wahl für einen FTP-Datentransfer.

Der große Vorteil der Verwendung eines PO-Systems für die Datenübertragung ist das zentrale Logging und das zentrale Montoring, einschließlich des Neustarts von FTP-Übertragungen nach einem Fehler.

Nehmen wir also an, du hast diese Alternative geprüft und bist zu dem Schluss gekommen, dass du weiterhin direkt aus ABAP heraus eine FTP-Verbindung aufbauen musst. Hier ist, was du tun musst.

Verbindungen zum FTP-Server zulassen

SAP hat eine zusätzliche Sicherheitsschicht für FTP-Verbindungen. Du kannst nur Verbindungen zu solchen Servern initiieren, die in der Tabelle SAPFTP_SERVERS aufgeführt sind. Bevor du also mit einem FTP-Server kommunizieren kannst, musst du diese Tabelle bearbeiten, entweder über SM30 oder über direkten Tabellenzugriff wie SE16N oder über einen anderen direkten Tabellenzugriff, je nachdem, was in deinem Unternehmen möglich und vor allem zulässig ist.

So sieht die Tabelle SAPFTP_SERVER aus:

Also brauchst du:

  • den Servernamen
  • den FTP-Port, normalerweise ist dies Port 21
  • eine Beschreibung, die an verschiedenen Stellen zur Anzeige kommt.

Das FTP-Passwort verschlüsseln

Der seltsame (und knifflige) Teil einer FTP-Übertragung direkt aus ABAP besteht darin, das Passwort zu verschlüsseln.

Die eigentliche FTP-Übertragung übernimmt ein von SAP bereitgestelltes Programm auf dem Application Server. Dieses Programm erwartet (wahrscheinlich aus Sicherheitsgründen) ein verschlüsseltes Passwort. Das macht nicht wirklich Sinn, da es davon ausgeht, dass der Anwendungsserver kompromittiert sein könnte. Aber wenn das der Fall ist, was würde dann noch alles kompromittiert sein? Trotzdem musst du das Passwort verschlüsseln.

Dazu kannst du den Funktionsbaustein HTTP_SCRAMBLE verwenden. Die Eingabe ist dein Passwort. Außerdem musst du die Passwortlänge separat übergeben. Die Ausgabe ist das verschlüsselte Passwort.

Der Schlüssel zum Verschlüsseln ist ‚26101957‘. Dieser Schlüssel ist fest, es ist genau der String, den das Kommandozeilenprogramm anschließend verwendet, um das Passwort zu entschlüsseln.

  lv_len = strlen( pa_pwd ).

  call function 'HTTP_SCRAMBLE'
    exporting
      source      = pa_pwd
      sourcelen   = lv_len
      key         = '26101957'
    importing
      destination = pa_pwd.

Die FTP-Verbindung mit Hilfe von ftp_connect aufbauen

Jetzt kannst du die FTP-Verbindung aufbauen. Hierzu verwendest du den Funktionsbaustein ftp_connect.

Du brauchst:

  • den Nutzernamen
  • das (verschlüsselte) Passwort
  • den Servernamen (denke daran, dass dieser Server in der Tabelle SAPFTP_SERVERS stehen muss)
  • und eine RFC-Destination

Die zu verwendende RFC-Destination ist ‚SAPFTPA‘. Dadurch wird eine FTP-Verbindung vom Anwendungsserver zum FTP-Server aufgebaut. Es ist auch möglich, die FTP-Verbindung stattdessen von der SAP GUI auf deinem Windows-PC aus zu starten. Dies würde bei der Batchverarbeitung aber nicht mehr funktionieren und im Allgemeinen wäre es aus Sicherheitsgründen eine schlechte Idee, deinen Windows-PC mit einem FTP-Server auf der anderen Seite des Planeten kommunizieren zu lassen. In der Regel werden deine Netzwerkeinstellungen in deiner Firma dies auch gar nicht zulassen. Daher werde ich dir jetzt nicht sagen, welche RFC-Destination du für diesen Zweck einsetzen könntest.

Die Rückgabe des Bausteins ist ein Handle, ein Integer-Code in einer internen Tabelle aktiver FTP-Verbindungen.

  call function 'FTP_CONNECT'
    exporting
      user             = pa_user
      password         = pa_pwd
*     ACCOUNT          =
      host             = pa_srvr
      rfc_destination  = 'SAPFTPA'
*     GATEWAY_USER     =
*     GATEWAY_PASSWORD =
*     GATEWAY_HOST     =
    importing
      handle           = lf_handle
    exceptions
      not_connected    = 1
      others           = 2.
  if sy-subrc <> 0.
    write: / 'abort in FTP_CONNECT with subrc=', sy-subrc.
    exit.
  endif.

Die FTP-Nutzdaten schreiben

Jetzt kannst du deine Nutzdaten über die FTP-Verbindung auf den Server schreiben. Hierzu dient der Funktionsbaustein FTP_R3_TO_SERVER. SAP erwartet die Daten in Form von Textzeilen. Das wird zumindest in diesem Beispiel verwendet. Der Funktionsbaustein hat auch einen Parameter „blob“ für Binärdaten, das ich bisher nicht verwendet habe.

Wichtiges Parameter des Aufrufs ist auch der Pfad auf dem Server, an dem die Datei abgelegt werden soll.

  call function 'FTP_R3_TO_SERVER'
    exporting
      handle         = lf_handle
      fname          = pa_path
      character_mode = 'X'
    tables
      text           = lt_text
    exceptions
      tcpip_error    = 1
      command_error  = 2
      data_error     = 3
      others         = 4.
  if sy-subrc <> 0.
    write: / 'abort in FTP_R3_TO_SERVER with subrc=', sy-subrc.
    exit.
  endif.

Die FTP-Verbindung wieder trennen.

Verggiss nicht , FTP_DISCONNECT aufzurufen, um die FTP-Verbindung wieder zu schließen.

  call function 'FTP_DISCONNECT'
    exporting
      handle = lf_handle.

Alles zusammenfügen

Hier ist der komplette ABAP-Code:

report zftp_transfer.

parameters: pa_srvr type char234 obligatory,
            pa_user type char234,
            pa_pwd type  char234,
            pa_path type char234 obligatory,
            pa_cont type char234 obligatory.

start-of-selection.

  data: lf_handle   type i,
        lv_len type i,
        lt_text     type table of char8000.

  write: / 'server', pa_srvr.
  write: / 'user', pa_user.
  write: / 'password', pa_pwd.
  write: / 'path', pa_path.
  write: / 'content', pa_cont.
exit.

  lv_len = strlen( pa_pwd ).

  call function 'HTTP_SCRAMBLE'
    exporting
      source      = pa_pwd
      sourcelen   = lv_len
      key         = '26101957'
    importing
      destination = pa_pwd.

  write: / 'scrambled password', pa_pwd.

  call function 'FTP_CONNECT'
    exporting
      user             = pa_user
      password         = pa_pwd
*     ACCOUNT          =
      host             = pa_srvr
      rfc_destination  = 'SAPFTPA'
*     GATEWAY_USER     =
*     GATEWAY_PASSWORD =
*     GATEWAY_HOST     =
    importing
      handle           = lf_handle
    exceptions
      not_connected    = 1
      others           = 2.
  if sy-subrc <> 0.
    write: / 'abort in FTP_CONNECT with subrc=', sy-subrc.
    exit.
  endif.

  " transfer content to string array
  append pa_cont to lt_text.

  call function 'FTP_R3_TO_SERVER'
    exporting
      handle         = lf_handle
      fname          = pa_path
      character_mode = 'X'
    tables
      text           = lt_text
    exceptions
      tcpip_error    = 1
      command_error  = 2
      data_error     = 3
      others         = 4.
  if sy-subrc <> 0.
    write: / 'abort in FTP_R3_TO_SERVER with subrc=', sy-subrc.
    exit.
  endif.

  call function 'FTP_DISCONNECT'
    exporting
      handle = lf_handle.

Ein letztes Wort der Warnung

Dieser Ansatz funktioniert. Ich weise aber noch einmal darauf hin, dass es in der Regel besser ist, ein SAP PO-System für FTP-Übertragungen zu verwenden. Du erhältst das Logging nebenbei, du erhältst das Monitoring nebenbei, die Customizingmöglichkeiten sind viel besser, du hast Unterstützung für http-Proxys usw.

Die direkte FTP-Übertragung in ABAP sollte nur eine seltene Ausnahme sein.

heiko

Dipl.-Ing. Heiko Evermann

Vorheriger Artikel