Gestion des composants logiciels dans ABAP Cloud

Catégorie
DevOps
Publié
Auteur
Johannes

Les composants logiciels sont le concept central pour structurer le code ABAP sur SAP BTP. Ils constituent la base pour le transport, le versionnage et la modularisation des objets de développement dans ABAP Cloud.

Qu’est-ce qu’un composant logiciel ?

Un composant logiciel est une unité logique qui regroupe des objets de développement ABAP connexes :

ConceptDescription
Software ComponentConteneur pour les packages ABAP et leurs objets
PackageDossier au sein d’un composant pour une structuration plus fine
RepositoryDépôt Git contenant le code du composant
BranchVersion/branche au sein du dépôt
CloneCopie locale du composant dans un système ABAP

Composants logiciels vs. packages classiques

AspectClassique (On-Premise)ABAP Cloud
Unité principalePackage (DEVC)Software Component
TransportOrdres de transportBasé sur Git via gCTS
VersionnageLogs de transportCommits/Branches Git
DépendancesInterfaces de packagesComponent Dependencies
ModularisationOptionnelleObligatoire

Architecture des composants logiciels

┌─────────────────────────────────────────────────────────────────────────────┐
│ SAP BTP ABAP Environment │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Software Component: /DMO/FLIGHT │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ /DMO/FLIGHT_ │ │ /DMO/FLIGHT_ │ │ /DMO/FLIGHT_ │ │ │
│ │ │ DOMAIN │ │ REUSE │ │ TRAVEL │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ - CDS Entities │ │ - Utility │ │ - RAP BO │ │ │
│ │ │ - Domain Types │ │ Classes │ │ - Service │ │ │
│ │ │ - Data Elements │ │ - Interfaces │ │ - Projection │ │ │
│ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │
│ │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘│ │
│ │ ↑ Git Repository ↑ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Software Component: ZCUSTOM_APP │ │
│ │ │ │
│ │ ┌─────────────────┐ ┌─────────────────┐ │ │
│ │ │ ZCUSTOM_CORE │ │ ZCUSTOM_UI │ │ │
│ │ │ │ │ │ │ │
│ │ │ - Business Logic│ │ - Services │ ─────depends on────────────┤ │
│ │ │ - RAP BO │ │ - Extensions │ /DMO/FLIGHT │ │
│ │ └─────────────────┘ └─────────────────┘ │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘

Créer un composant logiciel

Prérequis

  • Autorisation administrateur dans l’environnement ABAP
  • Accès à l’application Fiori Launchpad “Manage Software Components”
  • Dépôt Git (optionnel pour vos propres composants)

Étape 1 : Ouvrir l’application Manage Software Components

L’application “Manage Software Components” est le point d’entrée central :

┌────────────────────────────────────────────────────────────────┐
│ Manage Software Components │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Software Components │ │
│ │ │ │
│ │ Component │ Status │ Branch │ Last Commit │ │
│ │ ────────────────┼───────────┼─────────┼────────────── │ │
│ │ /DMO/FLIGHT │ Cloned │ main │ 2 hours ago │ │
│ │ ZCUSTOM_APP │ Not Cloned│ - │ - │ │
│ │ ZINTEGRATION │ Cloned │ develop │ 1 day ago │ │
│ │ │ │
│ │ [+ Create] [Clone] [Pull] [Checkout] │ │
│ └─────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────┘

Étape 2 : Créer un nouveau composant logiciel

" Un composant logiciel est créé via l'application Fiori :
" 1. Cliquer sur le bouton "Create"
" 2. Attribuer un nom (ex. ZCUSTOM_APP)
" 3. Ajouter une description
" 4. Optionnel : Indiquer l'URL du dépôt Git
ChampExempleDescription
NameZCUSTOM_APPNom technique unique
DescriptionCustom ApplicationDescription lisible
Repository URLhttps://github.com/Dépôt Git (optionnel)
BranchmainBranche par défaut

Étape 3 : Créer un package de structure

Chaque composant logiciel nécessite au moins un package de structure :

" Dans ADT : File > New > ABAP Package
" - Name : ZCUSTOM_APP (même nom que le composant)
" - Software Component : ZCUSTOM_APP
" - Package Type : Structure Package

Packages au sein d’un composant

Hiérarchie de packages

Software Component: ZCUSTOM_APP
├── ZCUSTOM_APP (Structure Package)
│ │
│ ├── ZCUSTOM_APP_DOMAIN (Development Package)
│ │ ├── CDS Views
│ │ ├── Data Elements
│ │ └── Domains
│ │
│ ├── ZCUSTOM_APP_CORE (Development Package)
│ │ ├── Classes
│ │ ├── Interfaces
│ │ └── RAP Business Objects
│ │
│ ├── ZCUSTOM_APP_SERVICE (Development Package)
│ │ ├── Service Definitions
│ │ ├── Service Bindings
│ │ └── Behavior Definitions
│ │
│ └── ZCUSTOM_APP_TEST (Development Package)
│ └── ABAP Unit Test Classes

Créer un package dans ADT

" File > New > ABAP Package
" 1. Package de développement pour objets de domaine :
" Name : ZCUSTOM_APP_DOMAIN
" Description : Domain objects for Custom App
" Software Component : ZCUSTOM_APP
" Superpackage : ZCUSTOM_APP
" Package Type : Development
" 2. Package de développement pour logique métier :
" Name : ZCUSTOM_APP_CORE
" Description : Core business logic
" Software Component : ZCUSTOM_APP
" Superpackage : ZCUSTOM_APP
" Package Type : Development

Dépendances entre composants

Types de dépendances

TypeDescriptionExemple
Dépendance directeLe composant utilise des objets d’un autreZCUSTOM utilise /DMO/FLIGHT
Dépendance transitiveDépendance indirecte via un tiersA → B → C
Dépendance circulaireDépendance mutuelle (interdite !)A → B → A

Déclarer une dépendance

Les dépendances sont gérées via les interfaces de packages :

-- Définir une interface de package (objets exportés)
-- Dans ADT : Package > New > ABAP Package Interface
-- Exemple : /DMO/FLIGHT_REUSE expose des classes utilitaires
@EndUserText.label: 'Flight Reuse Package Interface"
package interface /dmo/flight_reuse_api
{
-- Toutes les classes avec le préfixe CL_ sont exportées
expose classes matching 'CL_*';
-- Exporter des interfaces spécifiques
expose if_flight_calculator;
expose if_price_provider;
}

Use Access pour les dépendances

" Dans le package ZCUSTOM_APP_CORE :
" Clic droit > Properties > Use Accesses
" Ajouter un Use Access :
" - Package Interface : /DMO/FLIGHT_REUSE_API
" - Access Mode : Readonly

Exemple de code : utilisation entre composants

CLASS zcl_custom_flight_service DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
calculate_flight_price
IMPORTING iv_flight_id TYPE /dmo/flight_id
RETURNING VALUE(rv_price) TYPE /dmo/flight_price
RAISING cx_flight_not_found.
ENDCLASS.
CLASS zcl_custom_flight_service IMPLEMENTATION.
METHOD calculate_flight_price.
" Utilisation d'une classe de /DMO/FLIGHT_REUSE
" Cela ne fonctionne que si la dépendance est déclarée
DATA(lo_calculator) = NEW /dmo/cl_flight_price_calculator( ).
rv_price = lo_calculator->calculate(
iv_flight_id = iv_flight_id
iv_include_taxes = abap_true
).
ENDMETHOD.
ENDCLASS.

Cloner et mettre à jour un composant logiciel

Cloner un composant (première fois)

┌────────────────────────────────────────────────────────────────┐
│ Clone Software Component │
│ │
│ Component: ZPARTNER_INTEGRATION │
│ Repository: https://github.com/company/partner-integration │
│ Branch: main │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Clone Progress │ │
│ │ ████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 42% │ │
│ │ │ │
│ │ - Fetching repository metadata... ✓ │ │
│ │ - Downloading objects... ✓ │ │
│ │ - Importing ABAP objects... ⟳ │ │
│ │ - Activating objects... ○ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ [Cancel] │
└────────────────────────────────────────────────────────────────┘

Pull (récupérer les mises à jour)

" Code ABAP pour un pull programmatique
" (normalement via l'application Fiori)
CLASS zcl_software_component_utils DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
CLASS-METHODS:
get_component_info
IMPORTING iv_component_name TYPE string
RETURNING VALUE(rs_info) TYPE zsoftware_component_info.
ENDCLASS.
CLASS zcl_software_component_utils IMPLEMENTATION.
METHOD get_component_info.
" Lire les informations du composant logiciel
" via l'API correspondante
SELECT SINGLE
component_name,
current_branch,
last_commit_id,
last_commit_date,
clone_status
FROM i_softwarecomponent
WHERE component_name = @iv_component_name
INTO CORRESPONDING FIELDS OF @rs_info.
ENDMETHOD.
ENDCLASS.

Changer de branche (Checkout)

┌────────────────────────────────────────────────────────────────┐
│ Checkout Branch │
│ │
│ Component: ZCUSTOM_APP │
│ Current Branch: main │
│ │
│ Available Branches: │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ ○ main (default) │ │
│ │ ● develop ← Selected │ │
│ │ ○ feature/new-ui │ │
│ │ ○ hotfix/price-calc │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ⚠ Warning: Local changes will be overwritten! │
│ │
│ [Checkout] [Cancel] │
└────────────────────────────────────────────────────────────────┘

Transport et déploiement

Workflow de transport basé sur Git

┌─────────────────────────────────────────────────────────────────────────────┐
│ Flux de transport basé sur Git │
│ │
│ Système DEV Dépôt Git Système QAS/PRD │
│ ────────── ────────────── ────────────── │
│ │
│ 1. Développement 2. Commit/Push 4. Pull/Deploy │
│ ┌──────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ Modifier │ ────────────> │ main │ ────────> │ Import │ │
│ │ le code │ Push │ branch │ Pull │ Objects │ │
│ └──────────┘ └──────────────┘ └──────────┘ │
│ │ │
│ 3. Review │ │
│ ┌──────────┐ ┌──────────────┐ │
│ │ Pull │ <──────────── │ feature │ │
│ │ Request │ Review │ branch │ │
│ └──────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘

Workflow de release

" Processus de release du composant logiciel :
" 1. Développement sur une branche feature
" 2. Créer une pull request
" 3. Effectuer une revue de code
" 4. Merge dans la branche main
" 5. Créer un tag pour la release
" 6. QAS : Checkout du tag
" 7. Effectuer les tests
" 8. PRD : Checkout du même tag

Structuration de grands projets

Structure de composants recommandée

ComponentObjectifExemples de packages
Z*_FOUNDATIONObjets de base, domainesZ_DOMAIN, Z_TYPES
Z*_CORELogique métierZ_BO, Z_LOGIC
Z*_SERVICEAPIs et servicesZ_ODATA, Z_REST
Z*_UIObjets spécifiques à l’UIZ_FIORI, Z_ANNOTATIONS
Z*_INTEGRATIONIntégrations externesZ_RFC, Z_HTTP
Z*_TESTInfrastructure de testZ_UNIT, Z_MOCKS

Exemple : projet multi-composants

Enterprise Sales Application
├── ZSALES_FOUNDATION ← Aucune dépendance
│ ├── ZSALES_FOUNDATION_TYPES
│ └── ZSALES_FOUNDATION_UTILS
├── ZSALES_CORE ← Dépend de FOUNDATION
│ ├── ZSALES_CORE_ORDER
│ ├── ZSALES_CORE_CUSTOMER
│ └── ZSALES_CORE_PRODUCT
├── ZSALES_SERVICE ← Dépend de CORE
│ ├── ZSALES_SERVICE_ORDER_API
│ └── ZSALES_SERVICE_CUSTOMER_API
└── ZSALES_UI ← Dépend de SERVICE
├── ZSALES_UI_ORDER_APP
└── ZSALES_UI_CUSTOMER_APP

Bonnes pratiques

À faire

RecommandationJustification
Un composant = Un domaine métierResponsabilités claires
Définir des dépendances explicitesÉvite les couplages cachés
Utiliser les interfaces de packagesContrôle des APIs exportées
Convention de nommage cohérenteMeilleure visibilité dans le dépôt
Packages de test séparésSéparation propre du code de production
Définir une stratégie de branchesmain, develop, feature/*

À éviter

À éviterProblème
Tous les objets dans un composantConfus, difficile à maintenir
Dépendances circulairesErreurs de build, mises à jour complexes
Hiérarchies de packages trop profondesNavigation difficile
Noms génériques (ZUTILS, ZMISC)Peu clair, devient une poubelle
Packages sans périmètre clairMélange de responsabilités

Conventions de nommage

Type d’objetConventionExemple
Software ComponentZ{PROJET}_{DOMAINE}ZSALES_CORE
Structure Package= Nom du composant logicielZSALES_CORE
Development PackageZ{PROJET}{DOMAINE}{FONCTION}ZSALES_CORE_ORDER
Package InterfaceZ{PACKAGE}_APIZSALES_CORE_ORDER_API

Dépannage

Problèmes courants

ProblèmeCauseSolution
”Component not found”Clone manquantCloner le composant via Manage Software Components
”Dependency error”Use Access manquantVérifier Package Interface et Use Access
”Activation failed”Conflits d’objetsChanger de branche ou résoudre le conflit
”Pull failed”Authentification GitVérifier les credentials dans Destination Service

Outils de diagnostic

CLASS zcl_component_diagnostics DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
CLASS-METHODS:
check_component_status
IMPORTING iv_component TYPE string
RETURNING VALUE(rt_issues) TYPE string_table.
ENDCLASS.
CLASS zcl_component_diagnostics IMPLEMENTATION.
METHOD check_component_status.
" 1. Vérifier si le composant est cloné
SELECT SINGLE clone_status
FROM i_softwarecomponent
WHERE component_name = @iv_component
INTO @DATA(lv_status).
IF sy-subrc <> 0.
APPEND 'Composant non trouvé' TO rt_issues.
RETURN.
ENDIF.
IF lv_status <> 'CLONED'.
APPEND |Statut du composant : { lv_status }| TO rt_issues.
ENDIF.
" 2. Vérifier les objets non activés
SELECT COUNT(*)
FROM tadir
WHERE devclass LIKE @iv_component && '%"
AND obj_status <> 'A"
INTO @DATA(lv_inactive_count).
IF lv_inactive_count > 0.
APPEND |{ lv_inactive_count } objets inactifs| TO rt_issues.
ENDIF.
ENDMETHOD.
ENDCLASS.

Intégration avec CI/CD

Les composants logiciels peuvent être intégrés dans des pipelines CI/CD :

# Exemple : workflow GitHub Actions
name: ABAP CI/CD
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Import to ABAP System
uses: SAP/abap-pipeline-action@v1
with:
system-url: ${{ secrets.ABAP_SYSTEM_URL }}
component: ZCUSTOM_APP
branch: ${{ github.ref_name }}
- name: Run ABAP Unit Tests
uses: SAP/abap-unit-action@v1
with:
package: ZCUSTOM_APP
coverage-threshold: 80

Comparaison des options de transport

CaractéristiqueTransport classiquegCTSabapGit
Groupe cibleOn-PremiseOn-Premise + BTPTous
Intégration GitNonOuiOui
Support SAPOuiOuiCommunauté
BranchingNonOuiOui
CI/CDLimitéOuiOui
BTP ABAP EnvironmentN/AStandardVia ADT

Sujets avancés

Résumé

La gestion des composants logiciels est fondamentale pour le développement professionnel ABAP Cloud :

  1. Les composants logiciels regroupent les objets ABAP connexes
  2. Les packages permettent une structuration fine au sein d’un composant
  3. Les interfaces de packages contrôlent quels objets sont exportés
  4. Les dépendances entre composants doivent être déclarées explicitement
  5. Le transport basé sur Git remplace les ordres de transport classiques
  6. L’intégration CI/CD permet des pratiques DevOps modernes

Une structure de composants bien pensée est payante à long terme : le code reste maintenable, les équipes peuvent travailler en parallèle et les modifications peuvent être transportées en toute sécurité à travers le paysage.