← Tous les articles

Envoyer des fichiers d'AL11 vers un serveur SFTP avec SAP Cloud Integration

Un parcours complet — tester la connexion SSH, ajouter la clé d'hôte du partenaire dans known_hosts, construire l'iFlow et envoyer les fichiers d'AL11 avec un petit programme ABAP.

Cloud IntegrationSFTPSSHAL11ABAP

Un besoin très courant : S/4HANA écrit un fichier sur le serveur d'application (AL11) — factures, paiements, listes de stock — et un partenaire veut le recevoir sur son serveur SFTP. Dans cet article, nous construisons ce flux avec SAP Cloud Integration (inclus dans Integration Suite), du premier test de connexion jusqu'à l'arrivée du fichier chez le partenaire.

Le flux complet : AL11 → programme ABAP → iFlow → SFTP du partenaire
Le flux complet : AL11 → programme ABAP → iFlow → SFTP du partenaire

Le principe

Cloud Integration tourne dans le cloud et ne voit pas le système de fichiers de votre serveur d'application on-premise. Nous inversons donc le sens :

  1. Un petit programme ABAP lit le fichier dans AL11 et l'envoie à l'adresse HTTPS d'un iFlow.
  2. L'iFlow l'écrit sur le serveur du partenaire avec l'adaptateur SFTP receiver.
  3. Le programme déplace le fichier d'origine dans un dossier d'archive.

Autre option : un adaptateur SFTP sender qui interroge un serveur SFTP de votre réseau via le Cloud Connector. Cela suppose un serveur SFTP de votre côté ; l'approche ci-dessus ne demande rien de plus.

Ce qu'il faut demander au partenaire

Information Exemple
Hôte et port sftp.partner-example.com:22
Utilisateur s4_upload
Authentification Mot de passe ou clé publique
Répertoire cible /inbound/
Liste blanche d'IP ? Si oui, communiquez les adresses IP sortantes de votre région Cloud Integration

1. Tester la connexion et récupérer la clé d'hôte

Ouvrez Monitor → Integrations and APIs → Manage Security → Connectivity Tests, onglet SSH.

  • Host / Port : le serveur du partenaire
  • Proxy Type : Internet
  • Authentication : None pour le premier essai
  • Laissez Check Host Key décoché — nous ne connaissons pas encore la clé

Cliquez sur Send. Si le serveur est joignable, la réponse affiche sa clé d'hôte. Cliquez sur Copy Host Key.

Test de connexion SSH : le serveur répond avec sa clé d'hôte
Test de connexion SSH : le serveur répond avec sa clé d'hôte

Si le test se termine par un timeout, c'est presque toujours un pare-feu : le partenaire n'a pas encore autorisé vos adresses IP Cloud Integration.

2. Ajouter la clé d'hôte dans known_hosts

L'adaptateur SFTP ne se connecte qu'aux serveurs qu'il connaît. Cette liste est un élément de sécurité nommé known_hosts. C'est ce contrôle qui vous protège contre un serveur se faisant passer pour celui du partenaire.

Allez dans Manage Security → Security Material :

  • Si known_hosts existe déjà, téléchargez-le d'abord et ajoutez la nouvelle ligne à la fin. Ne chargez jamais un fichier contenant uniquement la nouvelle clé : les hôtes de toutes les autres intégrations seraient perdus.
  • Choisissez ensuite Upload → Known Hosts (SSH), gardez le nom known_hosts et déployez.
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
Chargement du fichier known_hosts complété
Chargement du fichier known_hosts complété

3. Enregistrer les identifiants

  • Mot de passe : Security Material → Create → User Credentials, par exemple SFTP_PARTNER_USER.
  • Clé publique : Keystore → Create → SSH Key. Téléchargez la clé OpenSSH publique et envoyez-la au partenaire — la clé privée ne quitte jamais le tenant. Dans l'adaptateur, vous la référencez via Private Key Alias.

4. Nouveau test — cette fois complet

De retour dans le test SSH :

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

Quand ce test est vert, le côté Cloud Integration est prêt. Toute erreur ultérieure viendra de l'iFlow ou de l'ABAP, ce qui simplifie beaucoup l'analyse.

5. Construire l'iFlow

L'iFlow et les paramètres du SFTP receiver
L'iFlow et les paramètres du SFTP receiver

Adaptateur HTTPS sender

  • Address : /al11/sftp-out
  • User Role : ESBMessaging.send
  • CSRF Protected : décoché — notre programme ABAP ne récupère pas de jeton

Dans la Runtime Configuration de l'iFlow, ajoutez FileName dans Allowed Header(s). Sinon Cloud Integration supprime l'en-tête et le nom du fichier est perdu.

Content Modifier — définir le nom du fichier cible :

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}

Adaptateur SFTP receiver

Champ Valeur
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 — plus sûr que d'écraser

Déployez l'iFlow et copiez son adresse depuis Monitor → Manage Integration Content.

6. Côté ABAP : SM59 et le programme

Créez une destination HTTP de type G dans SM59 :

  • Target Host : l'hôte runtime de votre tenant (...-rt.cfapps.<région>.hana.ondemand.com)
  • Port : 443, SSL : actif
  • Path Prefix : /http/al11/sftp-out
  • Logon : authentification basique avec clientid / clientsecret d'une clé de service Process Integration Runtime (plan integration-flow), ou un certificat client

Importez la chaîne de certificats du serveur dans STRUST (identité SSL client) pour que la connexion TLS fonctionne.

Les fichiers en attente dans AL11 :

Fichiers en attente dans le répertoire de sortie (AL11)
Fichiers en attente dans le répertoire de sortie (AL11)

Et le programme :

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

Pour la production, pensez à :

  • des noms de fichiers logiques (transaction FILE) au lieu de chemins libres, avec un contrôle d'autorisation sur S_DATASET ;
  • un job en arrière-plan (SM36) qui parcourt tout le répertoire au lieu d'un fichier par exécution.

7. Test de bout en bout

  1. Lancez le programme avec un nom de fichier présent dans AL11.
  2. Dans Monitor → Message Processing, le message doit être Completed.
  3. Le fichier se trouve dans /inbound/ chez le partenaire et a été déplacé dans archive/ dans AL11.

Dépannage

Symptôme Cause probable Solution
Auth fail / clé d'hôte refusée Clé absente ou modifiée Étape 2 — mettre à jour known_hosts
Timeout de connexion Pare-feu / liste blanche Le partenaire autorise vos IP CPI
No such file / accès refusé Mauvais répertoire ou droits Test avec Check Directory Access
HTTP 401 / 403 dans ABAP Client ID/secret ou rôle incorrect Vérifier la clé de service et ESBMessaging.send
HTTP 403 avec message CSRF Protection CSRF active Décocher CSRF Protected
Mauvais nom de fichier En-tête FileName supprimé L'ajouter dans Allowed Header(s)
« Le fichier existe déjà » Handling for Existing Files = Fail Ajouter un horodatage au nom

L'avantage de ce montage : chaque brique se teste séparément — la connexion SSH, l'iFlow et le programme ABAP. En cas de problème, vous savez tout de suite où chercher.

Commentaires

Laisser un commentaire