Clean Core est la réponse stratégique de SAP au problème vieux de plusieurs décennies des modifications SAP chaotiques et menaçant les mises à niveau. L’idée centrale : gardez le code SAP standard propre (clean) et réalisez les extensions uniquement via des interfaces définies et stables.
Le problème : les personnalisations SAP traditionnelles
Modifications classiques (avant Clean Core)
" ❌ MAUVAIS : Intervention directe dans le standard SAPENHANCEMENT-POINT ep_vbap_check IN PROGRAM sapmv45a. " Logique personnalisée directement dans le programme SAP standard IF vbap-matnr = 'SPECIAL'. vbap-kwmeng = vbap-kwmeng * 2. ENDIF.END-ENHANCEMENT-POINT.
" ❌ MAUVAIS : Utilisation de tables/champs non libérésSELECT SINGLE * FROM but000 WHERE partner = lv_partner." but000 n'est pas libéré → peut changer à tout moment !
" ❌ MAUVAIS : User-Exits/BADIs avec accès non propreMETHOD if_ex_badi_name~execute. " Accès direct aux structures internes SAP DATA(lv_internal) = cl_sap_internal_class=>get_data( ).ENDMETHOD.Les conséquences :
- 🔴 Les mises à niveau sont bloquées ou cassent les personnalisations
- 🔴 Coûts de maintenance élevés (en moyenne 30-40% du budget IT)
- 🔴 Innovation lente (peur des breaking changes)
- 🔴 La dette technique croît de manière exponentielle
Clean Core : La solution
Clean Core signifie une séparation stricte entre :
- Code standard SAP (Core) – intouché
- Extensions (Extensions) – uniquement via des APIs libérées
┌──────────────────────────────────────────────────────┐│ SAP Standard ││ (SAP S/4HANA Core) ││ ││ ┌─────────────────────────────────────────┐ ││ │ Released APIs & Extension Points │ ││ │ (Garanties stables par SAP) │ ││ └──────────────┬──────────────────────────┘ │└─────────────────┼───────────────────────────────────┘ │ │ Uniquement via des interfaces libérées │ ┌──────────▼──────────────────────────┐ │ Extensions Clean Core │ │ │ │ • Tier-3 : In-Stack (ABAP Cloud) │ │ • Key User Extensibility │ │ • Side-by-Side (BTP) │ │ • Intégration API │ └─────────────────────────────────────┘Les 3 Tiers : Modèle d’extensibilité
SAP définit un modèle d’extension à 3 niveaux :
Tier 1 : Developer Extensibility (Side-by-Side)
Principe : Les extensions s’exécutent sur SAP BTP (en dehors de S/4HANA)
" Développé sur BTP ABAP EnvironmentCLASS zcl_btp_sales_extension DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_oo_adt_classrun.ENDCLASS.
CLASS zcl_btp_sales_extension IMPLEMENTATION. METHOD if_oo_adt_classrun~main. " Accès à S/4HANA via OData/APIs DATA(lo_http) = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = 'https://my-s4hana.com/sap/opu/odata4/sap/api_salesorder_v1' ) ).
DATA(lo_request) = lo_http->get_http_request( ). lo_request->set_header_field( i_name = 'Accept' i_value = 'application/json' ).
DATA(lo_response) = lo_http->execute( if_web_http_client=>get ). DATA(lv_json) = lo_response->get_text( ).
" Logique métier propre " → Pas d'accès aux éléments internes S/4HANA " → Complètement isolé ENDMETHOD.ENDCLASS.Avantages :
- ✅ Découplage complet
- ✅ Cycle de release propre
- ✅ Mise à l’échelle indépendante de S/4HANA
- ✅ Tous les langages de programmation (ABAP, Java, Node.js…)
Inconvénients :
- ⚠️ Latence réseau (appels API)
- ⚠️ Complexité accrue (deux systèmes)
- ⚠️ Coûts de licence supplémentaires (BTP)
Tier 2 : Key User Extensibility (No-Code/Low-Code)
Principe : Les utilisateurs métier étendent S/4HANA sans code via des outils
Custom Fields (Champs personnalisés) :
SAP GUI → Paramètres → Custom Fields and Logic1. Sélectionner l'objet (ex. Sales Order)2. "Créer un nouveau champ"3. Nom du champ : ZZ_PRIORITY4. Type de données : String(10)5. Ajouter à l'UI→ Terminé ! Le champ est disponible dans la table, les CDS Views et l'UICustom Logic (Règles métier) :
1. Sélectionner le déclencheur : "Before Save - Sales Order"2. Condition : IF NetAmount > 100003. Action : SET ZZ_PRIORITY = 'HIGH"→ Aucune connaissance ABAP requise !Avantages :
- ✅ Rapide (minutes au lieu de jours)
- ✅ Pas de compétences développeur requises
- ✅ Intégré dans S/4HANA (pas de latence)
- ✅ Automatiquement sécurisé pour les mises à niveau
Inconvénients :
- ⚠️ Complexité limitée
- ⚠️ Uniquement pour les Business Objects libérés
Tier 3 : Developer Extensibility (In-Stack)
Principe : Développement ABAP à l’intérieur de S/4HANA avec ABAP Cloud
C’est le sweet spot pour les développeurs ABAP classiques :
" ✅ BON : Extension ABAP Cloud dans S/4HANA" Utiliser uniquement des APIs libéréesCLASS zcl_sales_validator DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_badi_interface.ENDCLASS.
CLASS zcl_sales_validator IMPLEMENTATION. METHOD if_badi_interface~validate. " Accès UNIQUEMENT via des APIs libérées SELECT SINGLE * FROM i_salesorder " ← CDS View libérée (libérée par SAP) WHERE salesorder = @iv_order_id INTO @DATA(ls_order).
" Logique métier IF ls_order-TotalNetAmount > 50000. " Message via API libérée DATA(lo_msg) = cl_message_helper=>get_instance( ). " ← Libérée lo_msg->add_message( id = 'ZMSG" number = '001" v1 = 'Approbation requise" ). ENDIF. ENDMETHOD.ENDCLASS.Comment reconnaître les APIs libérées ?
" Dans Eclipse ADT :" 1. Ouvrir l'API (ex. CDS View, Classe)" 2. Afficher les propriétés → "API State"" 3. Chercher "Released" ou "C1" (Cloud-Ready)
" Exemple : I_SalesOrder@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Sales Order"@Metadata.allowExtensions: true@ObjectModel.usageType.serviceQuality: #A@VDM.viewType: #BASIC
" → Si @VDM.viewType est présent : fait partie du Virtual Data Model (VDM)" = Libéré pour la consommation !
define view I_SalesOrder as select from vbak " ← vbak n'est PAS libéré, mais I_SalesOrder l'est !{ key vbeln as SalesOrder, erdat as CreationDate, netwr as TotalNetAmount, waerk as TransactionCurrency}Trouver les APIs libérées :
SAP API Business Hub : api.sap.com
Filtre : "API Type" → "ABAP Cloud" "Product" → "SAP S/4HANA"
Exemples :- I_SalesOrder, I_Customer, I_Product (CDS Views)- CL_BALI_LOG (Application Logging)- CL_NUMBERRANGE_RUNTIME (Number Ranges)- CL_WEB_HTTP_* (HTTP Client)Stratégie d’implémentation Clean Core
Phase 1 : Assessment (Analyse de l’existant)
Utiliser le Custom Code Analyzer :
" Transaction : ATC (ABAP Test Cockpit)" Ou dans Eclipse ADT :" Projet → Properties → ABAP Development → Code Inspector
" Check Variant : S4HANA_READINESS_REMOTE" → Affiche toutes les utilisations d'APIs non libéréesRésultats typiques :
| Catégorie | Exemple | Risque | Effort |
|---|---|---|---|
| Tables non libérées | SELECT FROM but000 | Élevé | Moyen |
| Implicit Enhancements | ENHANCEMENT-POINT | Élevé | Élevé |
| APIs non libérées | CALL FUNCTION 'RFC_READ_TABLE' | Moyen | Faible |
| Accès DB direct | OPEN CURSOR FOR SELECT * FROM (lv_tabname) | Très élevé | Élevé |
Phase 2 : Remédiation
Stratégie 1 : Remplacer les APIs
" ❌ Avant : Non libéréeSELECT SINGLE * FROM but000 WHERE partner = @lv_partner.
" ✅ Après : API libéréeSELECT SINGLE * FROM i_businesspartner WHERE businesspartner = @lv_partner INTO @DATA(ls_bp).Stratégie 2 : Couche Wrapper
" Wrapper central pour les accès critiquesCLASS zcl_bp_access DEFINITION PUBLIC CREATE PRIVATE. PUBLIC SECTION. CLASS-METHODS: get_instance RETURNING VALUE(ro_instance) TYPE REF TO zcl_bp_access,
get_business_partner IMPORTING iv_partner TYPE bu_partner RETURNING VALUE(rs_partner) TYPE i_businesspartner.
PRIVATE SECTION. CLASS-DATA go_instance TYPE REF TO zcl_bp_access.ENDCLASS.
CLASS zcl_bp_access IMPLEMENTATION. METHOD get_instance. IF go_instance IS NOT BOUND. CREATE OBJECT go_instance. ENDIF. ro_instance = go_instance. ENDMETHOD.
METHOD get_business_partner. " Aujourd'hui : API libérée SELECT SINGLE * FROM i_businesspartner WHERE businesspartner = @iv_partner INTO @rs_partner.
" Si l'API ne suffit pas : " TODO : Demander une extension d'API à SAP (via Influence Request) ENDMETHOD.ENDCLASS.
" Partout dans le code personnalisé :DATA(ls_bp) = zcl_bp_access=>get_instance( )->get_business_partner( lv_partner )." → Si SAP modifie l'API : modifier uniquement zcl_bp_access, pas 100 endroitsStratégie 3 : Refactoring vers RAP
" ❌ Avant : Programme Dynpro avec accès DB directREPORT zsales_order_maintain.
PARAMETERS: p_order TYPE vbeln.
START-OF-SELECTION. " Accès directs aux tables UPDATE vbak SET status = 'CLOSED' WHERE vbeln = p_order. COMMIT WORK.
" ✅ Après : RAP Business Object" → voir /rap-basics/ pour les détailsMODIFY ENTITIES OF i_salesordertp ENTITY SalesOrder UPDATE FIELDS ( OverallSDProcessStatus ) WITH VALUE #( ( SalesOrder = lv_order OverallSDProcessStatus = 'C' ) ) FAILED DATA(failed) REPORTED DATA(reported).
COMMIT ENTITIES.Phase 3 : Gouvernance (Rester Clean durablement)
1. ATC Checks dans le pipeline CI/CD
# Pipeline Azure DevOps / Jenkins- task: ABAP_ATC_Check inputs: checkVariant: 'CUSTOM_CLOUD_READINESS" failOnErrors: true excludePackages: '$TMP' # Exclure les développements de test2. Documenter les directives de développement
# Standards de développement ABAP (Exemple)
## Règles obligatoires1. ✅ Uniquement les APIs libérées (Vérifier : API Business Hub)2. ✅ Syntaxe ABAP Cloud (pas de CALL TRANSACTION, etc.)3. ✅ RAP pour les apps transactionnelles (pas de Dynpro)4. ✅ CDS Views au lieu de SELECT sur les tables DB5. ✅ Pas d'Implicit Enhancement Framework
## Recommandations- Classes wrapper pour les APIs fréquemment utilisées- Tests unitaires avec Test Doubles (voir /test-doubles-mocking/)- EML pour l'accès aux BO (voir /eml-guide/)3. Revues de code avec checklist
Checklist Pull Request :□ ATC-Check vert (Clean Core Variant) ?□ Uniquement des APIs libérées utilisées ?□ Tests unitaires présents (Couverture ≥ 80%) ?□ CDS Views documentées (Labels/Descriptions) ?□ Pas d'Implicit Enhancements ?Clean Core & ABAP Cloud
ABAP Cloud = implémentation technique de Clean Core
" ABAP Cloud Language Version : Le compilateur impose Clean Core !
CLASS zcl_order_processor DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_oo_adt_classrun.ENDCLASS.
CLASS zcl_order_processor IMPLEMENTATION. METHOD if_oo_adt_classrun~main. " ✅ Autorisé : API libérée SELECT * FROM i_salesorder INTO TABLE @DATA(lt_orders).
" ❌ Erreur de compilation : vbak n'est pas libérée ! " SELECT * FROM vbak INTO TABLE @DATA(lt_vbak). " → "vbak is not released for ABAP Cloud"
" ❌ Erreur de compilation : CALL TRANSACTION non autorisé " CALL TRANSACTION 'VA03'. " → "CALL TRANSACTION is not allowed in ABAP Cloud" ENDMETHOD.ENDCLASS.Activer ABAP Cloud dans S/4HANA :
Eclipse ADT :1. Créer/Ouvrir le package2. Properties → ABAP Language Version3. Sélectionner : "ABAP for Cloud Development"→ Tous les objets dans ce package sont conformes Clean Core !Migration : Étape par étape
Exemple : Sales Order Enhancement
Situation initiale (Classic ABAP) :
" ❌ User-Exit intégré dans le standard SAPENHANCEMENT-SECTION zenhancement_vbap IN sapmv45a. ENHANCEMENT 1 zorder_validation. " Accès aux variables globales du programme SAP IF vbap-matnr CO '0123456789'. MESSAGE 'Numéro de matériel invalide' TYPE 'E'. ENDIF. ENDENHANCEMENT.END-ENHANCEMENT-SECTION.Migration vers Clean Core (ABAP Cloud + RAP) :
" ✅ Étape 1 : Utiliser le BAdI (si disponible)CLASS zcl_order_badi DEFINITION PUBLIC. PUBLIC SECTION. INTERFACES if_ex_sd_sales_item_check. " ← BAdI SAPENDCLASS.
CLASS zcl_order_badi IMPLEMENTATION. METHOD if_ex_sd_sales_item_check~validate_item. " Accès uniquement via les paramètres de l'interface (pas d'accès global) IF is_item-material CO '0123456789'. " API libérée pour les messages DATA(lo_msg) = cl_bali_message_setter=>create( severity = if_bali_constants=>c_severity_error id = 'ZMSG" number = '001" ). APPEND lo_msg TO ct_messages. ENDIF. ENDMETHOD.ENDCLASS.
" ✅ Étape 2 : Si pas de BAdI → Wrapper Event" Voir RAP Business Events : /events-raise-handler/
" ✅ Étape 3 : À long terme → RAP Validation" Dans la Behavior Definition :validation validateMaterialNumber on save { field Material; }
" Behavior Implementation :METHOD validateMaterialNumber. READ ENTITIES OF zi_salesorder IN LOCAL MODE ENTITY SalesOrderItem FIELDS ( Material ) WITH CORRESPONDING #( keys ) RESULT DATA(lt_items).
LOOP AT lt_items INTO DATA(ls_item) WHERE Material CO '0123456789'. APPEND VALUE #( %tky = ls_item-%tky %element-Material = if_abap_behv=>mk-on ) TO failed-salesorderitem.
APPEND VALUE #( %tky = ls_item-%tky %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error text = 'Numéro de matériel invalide" ) ) TO reported-salesorderitem. ENDLOOP.ENDMETHOD.Outils pour Clean Core
| Outil | Objectif | Transaction/Lien |
|---|---|---|
| Custom Code Migration App | Analyse + Suivi | Fiori Launchpad : F2802 |
| ATC (ABAP Test Cockpit) | Analyse statique du code | SE80/ADT |
| SAP API Business Hub | Trouver les APIs libérées | api.sap.com |
| ABAP Cloud Flight Checker | Violations Clean Core | Eclipse ADT |
| Code Inspector | Vérifications legacy | SCI/ATC |
| Transport Dependency Analyzer | Analyse d’impact | SE03 |
Notes importantes / Bonnes pratiques
- Clean Core n’est pas une option : À partir de S/4HANA 2025+, ce sera obligatoire pour les éditions Cloud
- Commencez tôt : La migration prend 2-5 ans selon le volume de code personnalisé
- Règle 80/20 : 20% du code cause 80% des problèmes – priorisez !
- Utilisez SAP Influence : Une API libérée manque ? → influence.sap.com
- Ne pas tout migrer : Les anciens programmes peu utilisés peuvent être désactivés
- Pattern Wrapper : Encapsulez le code de transition dans des classes centrales
- ABAP Cloud = Support du compilateur : Utilisez la Language Version pour les nouveaux développements
- Test Doubles : Voir Test Doubles & Mocking pour des tests propres
- RAP-First : Nouvelles apps transactionnelles toujours avec RAP (voir RAP Basics)
- Documentation : Justifiez chaque écart (ex. “SAP livrera l’API dans la release XY”)
- Établir la gouvernance : Pull Requests + ATC-Checks = Clean Core durable
- Formation : Formez l’équipe – Clean Core est un changement de mentalité, pas seulement de syntaxe
Ressources supplémentaires
- ABAP Cloud : /abap-cloud-definition/
- Fondamentaux RAP : /rap-basics/
- Guide de migration : /migration-classic-to-cloud/