Remote Function Call (RFC) permet la communication synchrone entre systèmes SAP. Dans ABAP Cloud, les connexions RFC sont configurées via les Communication Arrangements et le Destination Service pour garantir une intégration sécurisée et maintenable.
RFC dans ABAP Cloud vs. ABAP classique
La communication RFC dans ABAP Cloud diffère fondamentalement de l’approche classique :
| Aspect | ABAP classique | ABAP Cloud |
|---|---|---|
| Configuration | SM59 RFC-Destination | Communication Arrangement |
| Appel | CALL FUNCTION … DESTINATION | Classes proxy via IF_PROXY_CLIENT |
| Authentification | Stockée dans SM59 | OAuth2, Certificats, Principal Propagation |
| Monitoring | SMGW, ST22 | SAP Cloud ALM, BTP Cockpit |
| Gestion des erreurs | COMMUNICATION_FAILURE | Classes d’exception |
| Disponibilité | Tous les FuBas | Uniquement les FuBas remote-enabled publiés |
Scénarios de communication
Vue d’ensemble des scénarios
Il existe trois scénarios principaux pour RFC dans ABAP Cloud :
┌─────────────────────────────────────────────────────────────────┐│ Scénario 1 : Cloud-to-Cloud ││ ┌──────────────┐ ┌──────────────┐ ││ │ ABAP Cloud │─────>│ ABAP Cloud │ ││ │ (BTP) │ RFC │ (BTP) │ ││ └──────────────┘ └──────────────┘ │├─────────────────────────────────────────────────────────────────┤│ Scénario 2 : Cloud-to-On-Premise (via Cloud Connector) ││ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ ││ │ ABAP Cloud │─────>│ SAP Cloud │─────>│ S/4HANA │ ││ │ (BTP) │ │ Connector │ │ On-Premise │ ││ └──────────────┘ └───────────────┘ └──────────────┘ │├─────────────────────────────────────────────────────────────────┤│ Scénario 3 : On-Premise-to-Cloud ││ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ ││ │ S/4HANA │─────>│ SAP Cloud │─────>│ ABAP Cloud │ ││ │ On-Premise │ │ Connector │ │ (BTP) │ ││ └──────────────┘ └───────────────┘ └──────────────┘ │└─────────────────────────────────────────────────────────────────┘RFC Cloud-to-Cloud
Pour la communication Cloud-to-Cloud, deux instances ABAP Environment se connectent directement :
Avantages :
- Aucune infrastructure supplémentaire nécessaire
- Authentification OAuth2 automatique
- Haute disponibilité grâce à l’infrastructure BTP
Limitations :
- Uniquement les Function Modules remote-enabled
- Pas de BAPIs classiques (uniquement les APIs publiées)
RFC Cloud-to-On-Premise
Pour la connexion aux systèmes On-Premise, le SAP Cloud Connector est nécessaire :
Composants :
- SAP Cloud Connector installé dans le réseau local
- Virtual Host Mapping pour la passerelle RFC
- Principal Propagation pour la transmission des utilisateurs
Configuration du Communication Arrangement
1. Créer le Communication Scenario
Le Communication Scenario définit les services outbound autorisés :
@EndUserText.label: 'RFC vers S/4HANA"@ObjectModel.usageType.serviceQuality: #Cdefine abstract entity ZA_RFC_S4_SCENARIO{ // Metadata pour Communication Scenario}Dans l’éditeur ADT pour les Communication Scenarios :
Communication Scenario: Z_RFC_S4HANADescription: Communication RFC vers S/4HANA
Outbound Services:├── RFC Service│ ├── Service ID: Z_RFC_S4_SERVICE│ ├── Service Type: RFC│ └── Allowed Destinations: Z_S4HANA_RFC_*2. Créer le Communication System
Le Communication System décrit le système cible :
┌──────────────────────────────────────────────────────────────┐│ Communication System: Z_S4HANA_PROD │├──────────────────────────────────────────────────────────────┤│ General Data: ││ ├── System ID: S4H ││ ├── System Name: S/4HANA Production ││ └── System Type: SAP System ││ ││ Technical Data (RFC): ││ ├── Host: s4hana.company.com ││ ├── Port: 443 (via Cloud Connector) ││ ├── Virtual Host: s4hana-virtual:3300 ││ └── Client: 100 ││ ││ User for Outbound Communication: ││ └── Authentication: OAuth 2.0 / Basic / Certificate │└──────────────────────────────────────────────────────────────┘3. Activer le Communication Arrangement
L’Arrangement connecte le Scenario au System :
┌──────────────────────────────────────────────────────────────┐│ Communication Arrangement: Z_RFC_S4HANA_PROD │├──────────────────────────────────────────────────────────────┤│ Communication Scenario: Z_RFC_S4HANA ││ Communication System: Z_S4HANA_PROD ││ ││ Outbound Services: ││ └── Z_RFC_S4_SERVICE: Active ✓ ││ ├── Path: /sap/bc/srt/rfc/sap/ ││ └── Authentication: OAuth2ClientCredentials │└──────────────────────────────────────────────────────────────┘Appel RFC via le Destination Service
Configurer la Destination
Dans le BTP Cockpit, la destination RFC est créée :
Name: S4HANA_RFCType: RFCProxyType: OnPremise (pour Cloud Connector)
RFC Properties:├── jco.client.ashost: s4hana-virtual├── jco.client.sysnr: 00├── jco.client.client: 100├── jco.client.lang: DE├── jco.destination.pool_capacity: 10└── jco.destination.peak_limit: 20
Authentication:├── Type: BasicAuthentication├── User: RFC_USER└── Password: ********
Location ID: <Cloud Connector Location>Générer le proxy RFC
Pour un appel RFC type-safe, un proxy est généré :
CLASS zcl_s4_material_proxy DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. TYPES: BEGIN OF ty_material, matnr TYPE c LENGTH 18, maktx TYPE c LENGTH 40, meins TYPE c LENGTH 3, mtart TYPE c LENGTH 4, END OF ty_material, tt_materials TYPE STANDARD TABLE OF ty_material WITH EMPTY KEY.
METHODS constructor RAISING cx_http_dest_provider_error.
METHODS get_material_details IMPORTING iv_matnr TYPE matnr RETURNING VALUE(rs_result) TYPE ty_material RAISING cx_rfc_dest_provider_error cx_communication_failure.
METHODS search_materials IMPORTING iv_search_term TYPE string RETURNING VALUE(rt_result) TYPE tt_materials RAISING cx_rfc_dest_provider_error cx_communication_failure.
PRIVATE SECTION. DATA mo_destination TYPE REF TO if_rfc_destination.ENDCLASS.
CLASS zcl_s4_material_proxy IMPLEMENTATION. METHOD constructor. " Récupérer la destination RFC du Destination Service mo_destination = cl_rfc_destination_provider=>create_by_cloud_destination( i_name = 'S4HANA_RFC' ). ENDMETHOD.
METHOD get_material_details. DATA: lv_matnr TYPE matnr, ls_material TYPE ty_material.
lv_matnr = iv_matnr.
" Appel RFC via proxy CALL FUNCTION 'BAPI_MATERIAL_GET_DETAIL" DESTINATION mo_destination->get_destination_name( ) EXPORTING material = lv_matnr IMPORTING material_general_data = ls_material EXCEPTIONS communication_failure = 1 system_failure = 2 OTHERS = 3.
IF sy-subrc <> 0. RAISE EXCEPTION TYPE cx_communication_failure EXPORTING textid = cx_communication_failure=>communication_failure. ENDIF.
rs_result = ls_material. ENDMETHOD.
METHOD search_materials. DATA: lt_matnr_range TYPE RANGE OF matnr, lt_materials TYPE tt_materials.
" Construire la plage de recherche APPEND VALUE #( sign = 'I" option = 'CP" low = |*{ iv_search_term }*| ) TO lt_matnr_range.
" Appel RFC CALL FUNCTION 'BAPI_MATERIAL_GETLIST" DESTINATION mo_destination->get_destination_name( ) TABLES matnrselection = lt_matnr_range matnrlist = lt_materials EXCEPTIONS communication_failure = 1 system_failure = 2 OTHERS = 3.
IF sy-subrc <> 0. RAISE EXCEPTION TYPE cx_communication_failure. ENDIF.
rt_result = lt_materials. ENDMETHOD.ENDCLASS.Utilisation dans RAP
Intégration du proxy RFC dans un RAP Business Object :
CLASS lhc_material DEFINITION INHERITING FROM cl_abap_behavior_handler. PRIVATE SECTION. METHODS get_external_data FOR READ IMPORTING keys FOR FUNCTION Material~getExternalData RESULT result.ENDCLASS.
CLASS lhc_material IMPLEMENTATION. METHOD get_external_data. TRY. DATA(lo_proxy) = NEW zcl_s4_material_proxy( ).
LOOP AT keys INTO DATA(ls_key). DATA(ls_material) = lo_proxy->get_material_details( iv_matnr = ls_key-MaterialNumber ).
APPEND VALUE #( %tky = ls_key-%tky %param-Description = ls_material-maktx %param-BaseUnit = ls_material-meins %param-MaterialType = ls_material-mtart ) TO result. ENDLOOP.
CATCH cx_http_dest_provider_error cx_communication_failure INTO DATA(lx_error). " Gestion des erreurs LOOP AT keys INTO ls_key. APPEND VALUE #( %tky = ls_key-%tky %fail = VALUE #( cause = if_abap_behv=>cause-unspecific ) ) TO failed-material. ENDLOOP. ENDTRY. ENDMETHOD.ENDCLASS.On-Premise vs. Cloud-to-Cloud
RFC Cloud-to-Cloud
Pour la communication purement Cloud, la configuration est plus simple :
CLASS zcl_cloud_rfc_client DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS call_remote_function IMPORTING iv_param TYPE string RETURNING VALUE(rv_result) TYPE string RAISING cx_rfc_dest_provider_error.ENDCLASS.
CLASS zcl_cloud_rfc_client IMPLEMENTATION. METHOD call_remote_function. " Destination Cloud directe (sans Cloud Connector) DATA(lo_destination) = cl_rfc_destination_provider=>create_by_cloud_destination( i_name = 'ABAP_CLOUD_SYSTEM_2' ).
" Appel RFC vers un autre système ABAP Cloud CALL FUNCTION 'Z_REMOTE_FUNCTION" DESTINATION lo_destination->get_destination_name( ) EXPORTING iv_input = iv_param IMPORTING ev_output = rv_result EXCEPTIONS communication_failure = 1 system_failure = 2 OTHERS = 3.
IF sy-subrc <> 0. RAISE EXCEPTION TYPE cx_rfc_dest_provider_error. ENDIF. ENDMETHOD.ENDCLASS.Destination BTP pour Cloud-to-Cloud :
Name: ABAP_CLOUD_SYSTEM_2Type: RFCProxyType: Internet
Authentication: OAuth2SAMLBearerAssertionToken Service URL: https://other-abap-system.authentication.eu10.hana.ondemand.com/oauth/token
Additional Properties:├── jco.client.ashost: other-abap-system-api.cfapps.eu10.hana.ondemand.com├── jco.client.sysnr: 00└── jco.client.client: 100RFC On-Premise avec Cloud Connector
Pour les systèmes On-Premise, une configuration supplémentaire est requise dans le Cloud Connector :
┌──────────────────────────────────────────────────────────────┐│ Cloud Connector Mapping │├──────────────────────────────────────────────────────────────┤│ Backend Type: ABAP System ││ ││ Virtual Host: s4hana-virtual ││ Virtual Port: 3300 ││ Internal Host: s4hana.internal.company.com ││ Internal Port: 3300 ││ ││ Protocol: RFC ││ Principal Type: X.509 Certificate (Recommandé) ││ ││ Resources: ││ └── All (ou Function Modules spécifiques) │└──────────────────────────────────────────────────────────────┘Gestion des erreurs et Timeout
Classes d’exception
CLASS zcl_rfc_handler DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. METHODS execute_rfc RETURNING VALUE(rv_result) TYPE string RAISING zcx_rfc_error.ENDCLASS.
CLASS zcl_rfc_handler IMPLEMENTATION. METHOD execute_rfc. TRY. DATA(lo_destination) = cl_rfc_destination_provider=>create_by_cloud_destination( i_name = 'S4HANA_RFC' ).
CATCH cx_rfc_dest_provider_error INTO DATA(lx_dest). " Destination non trouvée ou mal configurée RAISE EXCEPTION TYPE zcx_rfc_error EXPORTING previous = lx_dest textid = zcx_rfc_error=>destination_not_found. ENDTRY.
" Appel RFC avec gestion détaillée des erreurs DATA lv_message TYPE c LENGTH 200.
CALL FUNCTION 'Z_REMOTE_FUNCTION" DESTINATION lo_destination->get_destination_name( ) IMPORTING ev_result = rv_result EXCEPTIONS communication_failure = 1 MESSAGE lv_message system_failure = 2 MESSAGE lv_message OTHERS = 3.
CASE sy-subrc. WHEN 0. " Succès RETURN.
WHEN 1. " Erreur réseau, timeout, système inaccessible RAISE EXCEPTION TYPE zcx_rfc_error EXPORTING textid = zcx_rfc_error=>communication_failure message = CONV #( lv_message ).
WHEN 2. " Erreur ABAP dans le système cible (dump, exception) RAISE EXCEPTION TYPE zcx_rfc_error EXPORTING textid = zcx_rfc_error=>system_failure message = CONV #( lv_message ).
WHEN OTHERS. " Erreur inconnue RAISE EXCEPTION TYPE zcx_rfc_error EXPORTING textid = zcx_rfc_error=>unknown_error. ENDCASE. ENDMETHOD.ENDCLASS.Configuration du timeout
Les timeouts sont configurés dans la destination :
Name: S4HANA_RFC
Additional Properties:├── jco.destination.expiration_time: 60000 " ms jusqu'au nettoyage de connexion├── jco.destination.expiration_period: 60000 " Intervalle de vérification├── jco.destination.max_get_time: 30000 " Temps d'attente max pour connexion├── jco.client.cpic_timeout: 120 " Secondes pour l'appel RFC└── jco.destination.peak_limit: 10 " Connexions parallèles maxImplémenter la logique de retry
CLASS zcl_rfc_retry_handler DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION. CONSTANTS: c_max_retries TYPE i VALUE 3, c_retry_delay TYPE i VALUE 2000. " ms
METHODS call_with_retry IMPORTING iv_function TYPE rs38l_fnam RETURNING VALUE(rv_result) TYPE string RAISING zcx_rfc_error.ENDCLASS.
CLASS zcl_rfc_retry_handler IMPLEMENTATION. METHOD call_with_retry. DATA: lv_retries TYPE i, lv_message TYPE c LENGTH 200.
DATA(lo_destination) = cl_rfc_destination_provider=>create_by_cloud_destination( i_name = 'S4HANA_RFC' ).
WHILE lv_retries < c_max_retries. CALL FUNCTION iv_function DESTINATION lo_destination->get_destination_name( ) IMPORTING ev_result = rv_result EXCEPTIONS communication_failure = 1 MESSAGE lv_message system_failure = 2 MESSAGE lv_message OTHERS = 3.
CASE sy-subrc. WHEN 0. " Succès - retour immédiat RETURN.
WHEN 1. " Erreur de communication - retry pertinent lv_retries = lv_retries + 1.
IF lv_retries < c_max_retries. " Backoff exponentiel DATA(lv_wait) = c_retry_delay * lv_retries. cl_abap_session_context=>sleep( lv_wait ). ENDIF.
WHEN 2. " Erreur système - pas de retry car erreur logique RAISE EXCEPTION TYPE zcx_rfc_error EXPORTING textid = zcx_rfc_error=>system_failure message = CONV #( lv_message ).
WHEN OTHERS. RAISE EXCEPTION TYPE zcx_rfc_error EXPORTING textid = zcx_rfc_error=>unknown_error. ENDCASE. ENDWHILE.
" Max retries atteint RAISE EXCEPTION TYPE zcx_rfc_error EXPORTING textid = zcx_rfc_error=>max_retries_exceeded message = |Max. { c_max_retries } tentatives atteintes : { lv_message }|. ENDMETHOD.ENDCLASS.Monitoring et dépannage
Implémenter le logging
METHOD call_with_logging. DATA lo_log TYPE REF TO if_bali_log.
TRY. " Créer le log lo_log = cl_bali_log=>create_with_header( header = cl_bali_header_setter=>create( object = 'Z_RFC_LOG" subobject = 'RFC_CALLS" external_id = |RFC_{ sy-datum }_{ sy-uzeit }| ) ).
" Entrée de démarrage lo_log->add_item( item = cl_bali_free_text_setter=>create( severity = if_bali_constants=>c_severity_information text = |Appel RFC démarré : { iv_function }| ) ).
DATA(lv_start) = utclong_current( ).
" Exécuter RFC DATA(lv_result) = execute_rfc( iv_function ).
DATA(lv_end) = utclong_current( ). DATA(lv_duration) = cl_abap_utclong=>diff( high = lv_end low = lv_start ).
" Logger le succès lo_log->add_item( item = cl_bali_free_text_setter=>create( severity = if_bali_constants=>c_severity_status text = |RFC réussi, durée : { lv_duration-second } secondes| ) ).
rv_result = lv_result.
CATCH zcx_rfc_error INTO DATA(lx_error). " Logger l'erreur lo_log->add_item( item = cl_bali_free_text_setter=>create( severity = if_bali_constants=>c_severity_error text = |Erreur RFC : { lx_error->get_text( ) }| ) ).
RAISE EXCEPTION lx_error.
CLEANUP. " Sauvegarder le log IF lo_log IS BOUND. cl_bali_log_db=>get_instance( )->save_log( log = lo_log ). ENDIF. ENDTRY.ENDMETHOD.Erreurs fréquentes et solutions
| Erreur | Cause | Solution |
|---|---|---|
| COMMUNICATION_FAILURE | Réseau, timeout | Vérifier Cloud Connector, augmenter timeout |
| SYSTEM_FAILURE | Dump dans le système cible | Vérifier ST22 dans le système cible |
| RFC_ERROR_LOGON_FAILURE | Authentification | Vérifier les credentials dans la destination |
| RFC_ERROR_SYSTEM_BUSY | Surcharge | Augmenter peak_limit, retry |
| RFC_ERROR_COMMUNICATION | Problème gateway | Redémarrer Cloud Connector |
Bonnes pratiques
| Thème | Recommandation |
|---|---|
| Type de destination | Destination RFC uniquement pour les vrais appels RFC, pas pour HTTP |
| Connection Pool | Définir pool_capacity et peak_limit appropriés |
| Timeout | Timeouts réalistes basés sur la durée attendue |
| Gestion des erreurs | Toujours évaluer EXCEPTIONS, utiliser MESSAGE lv_message |
| Retry | Uniquement pour COMMUNICATION_FAILURE, pas pour SYSTEM_FAILURE |
| Logging | Logger tous les appels RFC pour le débogage |
| Testing | Destinations séparées pour DEV/QA/PROD |
| Sécurité | Autorisations RFC minimales dans le système cible |
Sujets connexes
- SAP Destination Service - Configurer les destinations
- HTTP Client - Alternative pour les APIs REST
- RAP Custom Entities - Intégrer des données externes dans RAP