← Alle Artikel

Dateien aus AL11 mit SAP Cloud Integration an einen SFTP-Server senden

Eine komplette Anleitung — SSH-Verbindung testen, den Host-Key des Partners in known_hosts aufnehmen, den iFlow bauen und Dateien aus AL11 mit einem kleinen ABAP-Report senden.

Cloud IntegrationSFTPSSHAL11ABAP

Eine sehr häufige Anforderung: S/4HANA schreibt eine Datei auf den Applikationsserver (AL11) — Rechnungen, Zahlungen, Bestandslisten — und ein Partner möchte sie auf seinem SFTP-Server haben. In diesem Artikel bauen wir den Ablauf mit SAP Cloud Integration (Teil der Integration Suite) auf: vom ersten Verbindungstest bis zur angekommenen Datei.

Der gesamte Ablauf: AL11 → ABAP-Report → iFlow → SFTP des Partners
Der gesamte Ablauf: AL11 → ABAP-Report → iFlow → SFTP des Partners

Die Idee

Cloud Integration läuft in der Cloud und sieht das Dateisystem Ihres On-Premise-Applikationsservers nicht. Deshalb drehen wir die Richtung um:

  1. Ein kleiner ABAP-Report liest die Datei aus AL11 und sendet sie an den HTTPS-Endpunkt eines iFlows.
  2. Der iFlow schreibt sie mit dem SFTP-Receiver-Adapter auf den Server des Partners.
  3. Der Report verschiebt die Originaldatei in einen Archivordner.

Alternativ kann ein SFTP-Sender-Adapter über den Cloud Connector einen SFTP-Server in Ihrem Netz abfragen. Dafür braucht es aber einen eigenen SFTP-Server; der Push-Ansatz oben kommt ohne aus.

Was Sie vom Partner brauchen

Information Beispiel
Host und Port sftp.partner-example.com:22
Benutzer s4_upload
Authentifizierung Passwort oder Public Key
Zielverzeichnis /inbound/
IP-Allowlist? Falls ja, die ausgehenden IP-Adressen Ihrer Cloud-Integration-Region mitteilen

1. Verbindung testen und Host-Key holen

Öffnen Sie Monitor → Integrations and APIs → Manage Security → Connectivity Tests und wechseln Sie auf den Reiter SSH.

  • Host / Port: der Server des Partners
  • Proxy Type: Internet
  • Authentication: zunächst None
  • Check Host Key nicht ankreuzen — den Schlüssel kennen wir noch nicht

Auf Send klicken. Ist der Server erreichbar, zeigt die Antwort seinen Host-Key. Mit Copy Host Key kopieren.

SSH-Verbindungstest: Der Server antwortet mit seinem Host-Key
SSH-Verbindungstest: Der Server antwortet mit seinem Host-Key

Endet der Test mit einem Timeout, ist es fast immer eine Firewall: Der Partner hat Ihre Cloud-Integration-IP-Adressen noch nicht freigegeben.

2. Host-Key in known_hosts aufnehmen

Der SFTP-Adapter verbindet sich nur mit Servern, die er kennt. Diese Liste ist ein Security Material namens known_hosts. Genau diese Prüfung schützt davor, dass sich jemand als Server des Partners ausgibt.

Unter Manage Security → Security Material:

  • Gibt es known_hosts bereits, laden Sie die Datei zuerst herunter und hängen die neue Zeile am Ende an. Laden Sie nie eine Datei hoch, die nur den neuen Schlüssel enthält — sonst gehen die Hosts aller anderen Integrationen verloren.
  • Dann Upload → Known Hosts (SSH) wählen, den Namen known_hosts beibehalten und deployen.
known_hosts.txt
# one line per host:  <host> <key type> <base64 public key>
sftp.old-partner.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7v...
sftp.partner-example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM8wq2xYkRb4Tq3Vn0e7HhGfPz1cL5uXo9Ks2dWm4AaQe
Hochladen der erweiterten known_hosts-Datei
Hochladen der erweiterten known_hosts-Datei

3. Zugangsdaten hinterlegen

  • Passwort: Security Material → Create → User Credentials, z. B. SFTP_PARTNER_USER.
  • Public Key: Keystore → Create → SSH Key. Den öffentlichen OpenSSH-Schlüssel herunterladen und dem Partner schicken — der private Schlüssel verlässt den Tenant nie. Im Adapter wird er über Private Key Alias referenziert.

4. Erneut testen — diesmal vollständig

Zurück im SSH-Verbindungstest:

  • Authentication: User Credentials mit SFTP_PARTNER_USER (oder Public Key)
  • Check Host Key: ✓
  • Check Directory Access: ✓ mit /inbound/

Ist dieser Test grün, ist die Cloud-Integration-Seite fertig. Alle weiteren Fehler liegen im iFlow oder im ABAP — das macht die Fehlersuche deutlich einfacher.

5. Den iFlow bauen

Der iFlow und die Einstellungen des SFTP-Receivers
Der iFlow und die Einstellungen des SFTP-Receivers

HTTPS-Sender-Adapter

  • Address: /al11/sftp-out
  • User Role: ESBMessaging.send
  • CSRF Protected: nicht angekreuzt — unser ABAP-Report holt kein Token

In der Runtime Configuration des iFlows FileName unter Allowed Header(s) eintragen. Sonst verwirft Cloud Integration den Header und der Dateiname geht verloren.

Content Modifier — den Zieldateinamen festlegen:

content-modifier.txt
Message Header
  Name:        TargetFile
  Source Type: Expression
  Source Value: ${header.FileName}

Optional – add a timestamp to avoid overwriting:
  Source Value: ${date:now:yyyyMMdd_HHmmss}_${header.FileName}

SFTP-Receiver-Adapter

Feld Wert
Address sftp.partner-example.com:22
Proxy Type Internet
Authentication User Name/Password
Credential Name SFTP_PARTNER_USER
Directory /inbound/
File Name ${header.TargetFile}
Handling for Existing Files Fail — sicherer als Überschreiben

Den iFlow deployen und den Endpunkt unter Monitor → Manage Integration Content kopieren.

6. Die ABAP-Seite: SM59 und der Report

In SM59 eine HTTP-Destination vom Typ G anlegen:

  • Target Host: der Runtime-Host Ihres Tenants (...-rt.cfapps.<region>.hana.ondemand.com)
  • Port: 443, SSL: aktiv
  • Path Prefix: /http/al11/sftp-out
  • Anmeldung: Basic Authentication mit clientid / clientsecret aus einem Service Key der Process Integration Runtime (Plan integration-flow) oder ein Client-Zertifikat

Die Zertifikatskette des Servers in STRUST (SSL-Client-Identität) importieren, damit der TLS-Handshake funktioniert.

Die wartenden Dateien in AL11:

Wartende Dateien im Ausgangsverzeichnis (AL11)
Wartende Dateien im Ausgangsverzeichnis (AL11)

Und der Report:

zal11_to_cpi_sftp.prog.abap
REPORT zal11_to_cpi_sftp.

" Reads a file from the application server (AL11), posts it to a
" Cloud Integration iFlow and moves it to an archive folder.
" Classic ABAP (on-premise): OPEN DATASET is not available in ABAP Cloud.

PARAMETERS: p_dir  TYPE c LENGTH 200 LOWER CASE DEFAULT '/interface/sftp_out/',
            p_file TYPE c LENGTH 120 LOWER CASE OBLIGATORY,
            p_arch TYPE c LENGTH 200 LOWER CASE DEFAULT '/interface/sftp_out/archive/'.

CONSTANTS c_destination TYPE rfcdest VALUE 'ZCPI_SFTP_OUT'.

START-OF-SELECTION.
  DATA(path)    = |{ p_dir }{ p_file }|.
  DATA(archive) = |{ p_arch }{ p_file }|.
  DATA content TYPE xstring.

  " 1. Read the file from AL11
  TRY.
      OPEN DATASET path FOR INPUT IN BINARY MODE.
      IF sy-subrc <> 0.
        MESSAGE |File { path } cannot be opened| TYPE 'E'.
      ENDIF.
      READ DATASET path INTO content.
      CLOSE DATASET path.
    CATCH cx_sy_file_access_error INTO DATA(file_error).
      MESSAGE file_error->get_text( ) TYPE 'E'.
  ENDTRY.

  " 2. Post it to the iFlow (SM59 destination of type G)
  DATA client TYPE REF TO if_http_client.
  cl_http_client=>create_by_destination(
    EXPORTING  destination = c_destination
    IMPORTING  client      = client
    EXCEPTIONS OTHERS      = 1 ).
  IF sy-subrc <> 0.
    MESSAGE |Destination { c_destination } cannot be used (SM59)| TYPE 'E'.
  ENDIF.

  client->request->set_method( if_http_request=>co_request_method_post ).
  client->request->set_content_type( 'application/octet-stream' ).
  client->request->set_header_field( name = 'FileName' value = CONV #( p_file ) ).
  client->request->set_data( content ).

  client->send( EXCEPTIONS OTHERS = 1 ).
  IF sy-subrc = 0.
    client->receive( EXCEPTIONS OTHERS = 1 ).
  ENDIF.
  IF sy-subrc <> 0.
    DATA error_text TYPE string.
    client->get_last_error( IMPORTING message = error_text ).
    MESSAGE error_text TYPE 'E'.
  ENDIF.

  DATA status TYPE i.
  DATA reason TYPE string.
  client->response->get_status( IMPORTING code = status reason = reason ).
  client->close( ).
  IF status <> 200.
    MESSAGE |Cloud Integration answered { status } { reason }| TYPE 'E'.
  ENDIF.

  " 3. Archive: write a copy, then delete the original
  OPEN DATASET archive FOR OUTPUT IN BINARY MODE.
  TRANSFER content TO archive.
  CLOSE DATASET archive.
  DELETE DATASET path.

  MESSAGE |{ p_file } sent to the SFTP server and archived| TYPE 'S'.

Für den produktiven Einsatz:

  • Logische Dateinamen (Transaktion FILE) statt freier Pfade und eine Berechtigungsprüfung auf S_DATASET.
  • Ein Hintergrundjob (SM36), der das ganze Verzeichnis abarbeitet statt einer Datei pro Lauf.

7. End-to-End-Test

  1. Den Report mit einem Dateinamen aus AL11 ausführen.
  2. Unter Monitor → Message Processing sollte die Nachricht Completed sein.
  3. Die Datei liegt beim Partner in /inbound/, in AL11 wurde sie nach archive/ verschoben.

Fehlersuche

Symptom Wahrscheinliche Ursache Lösung
Auth fail / Host-Key abgelehnt Host-Key fehlt oder hat sich geändert Schritt 2 — known_hosts aktualisieren
Verbindungs-Timeout Firewall / Allowlist Partner gibt Ihre CPI-IP-Adressen frei
No such file / keine Berechtigung Falsches Verzeichnis oder Rechte Test mit Check Directory Access
HTTP 401 / 403 im ABAP Falsche Client-ID/Secret oder Rolle Service Key und ESBMessaging.send prüfen
HTTP 403 mit CSRF-Meldung CSRF-Schutz aktiv CSRF Protected abwählen
Datei hat falschen Namen Header FileName verworfen In Allowed Header(s) eintragen
„Datei existiert bereits" Handling for Existing Files = Fail Zeitstempel im Dateinamen

Das Schöne an diesem Aufbau: Jeder Teil lässt sich einzeln testen — die SSH-Verbindung, der iFlow und der ABAP-Report. Wenn etwas klemmt, wissen Sie sofort, wo Sie suchen müssen.

Kommentare

Kommentar schreiben