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.
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 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 :
- Un petit programme ABAP lit le fichier dans AL11 et l'envoie à l'adresse HTTPS d'un iFlow.
- L'iFlow l'écrit sur le serveur du partenaire avec l'adaptateur SFTP receiver.
- 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 :
Nonepour 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.
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_hostsexiste 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_hostset déployez.
# one line per host: <host> <key type> <base64 public key>
sftp.old-partner.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7v...
sftp.partner-example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM8wq2xYkRb4Tq3Vn0e7HhGfPz1cL5uXo9Ks2dWm4AaQe
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 CredentialsavecSFTP_PARTNER_USER(ouPublic 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
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 :
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/clientsecretd'une clé de service Process Integration Runtime (planintegration-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 :
Et le programme :
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 surS_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
- Lancez le programme avec un nom de fichier présent dans AL11.
- Dans Monitor → Message Processing, le message doit être Completed.
- Le fichier se trouve dans
/inbound/chez le partenaire et a été déplacé dansarchive/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