Skip to content

[PORTAGE] Système de migration automatique des configurations de SI Openadom

Contexte

Openadom est une application générique permettant de créer des SI sur la base d'un fichier de configuration décrivant un domaine. Actuellement, la mise à jour d'un fichier de configuration nécessite une intervention manuelle pour adapter le schéma PostgreSQL et les données existantes.

Problématique

Lorsqu'un fichier de configuration est mis à jour, les conséquences sont très variables :

  • Aucune influence : le nouveau schéma est parfaitement géré sans intervention
  • Changements nécessaires : le schéma implique des modifications dans les types, index, et valeurs stockées en JSONB
  • Impossibilité : le schéma rend les données inutilisables, l'opération doit être interdite

Objectif

Mettre en place un mécanisme automatique permettant de :

  1. Identifier les changements entre deux fichiers de configuration (YAML/JSON)
  2. Classifier les changements selon leur impact (SAFE/TRANSFORMABLE/BREAKING/FORBIDDEN)
  3. Appliquer automatiquement les règles de portage appropriées
  4. Générer et exécuter les migrations PostgreSQL nécessaires
  5. Verrouiller l'accès au schéma pendant le portage

Solutions retenues

Architecture technique

Stack technologique :

  • Java 25, Spring Boot 4.0, PostgreSQL 18, Maven
  • JaVers 7.x : détection et comparaison des différences entre configurations
  • Easy Rules 4.x : moteur de règles pour classifier et gérer les migrations
  • networknt/json-schema-validator : validation des schémas JSONB
  • Flyway : exécution des migrations PostgreSQL

Composants applicatifs :

  1. ConfigurationComparator (JaVers)
    • Compare les configurations old/new
    • Génère l'arbre des différences avec GlobalId hiérarchiques
  2. ChangeAnalyzer
    • Extrait les changements JaVers
    • Transforme en objets ConfigurationChange métier
    • Expose la hiérarchie complète (datadescription/componentdescriptions/checker)
  3. MigrationRuleEngine (Easy Rules)
    • Évalue chaque changement avec les règles définies
    • Construit le MigrationPlan avec actions et niveau de risque
  4. MigrationPlanBuilder
    • Agrège les actions de migration
    • Valide la faisabilité globale
    • Génère le SQL dynamique (index, types composites, fonctions)
  5. SchemaValidator
    • Valide les schémas JSON avant application
    • Vérifie la compatibilité des données existantes
  6. MigrationExecutor
    • Verrouille l'accès au schéma SI
    • Exécute les migrations Flyway
    • Rollback automatique en cas d'échec

Découpage selon intervention

Niveau 1 - Configuration seule (SAFE) :

  • Pas d'intervention sur la base
  • Simple enregistrement dans table application (public.application)
  • Exemples : ajout champ optionnel, modification i18n, ajout tag

Niveau 2 - Schéma sans données (SAFE) :

  • Intervention sur le schéma uniquement
  • Pas de transformation de données
  • Exemples : ajout ReferenceType, création index, ajout function

Niveau 3 - Schéma avec transformation (TRANSFORMABLE) :

  • Intervention sur schéma ET données
  • Transformation automatique possible
  • Exemples : renommage champ, changement type compatible, ajout contrainte

Niveau 4 - Validation manuelle requise (BREAKING) :

  • Intervention complexe nécessitant validation
  • Risque de perte de données
  • Exemples : suppression champ obligatoire, changement référence

Niveau 5 - Opération interdite (FORBIDDEN) :

  • Aucune migration automatique possible
  • Exemples : suppression ReferenceType avec données, changement type incompatible

Verrouillage pendant portage

Mécanisme de verrouillage à implémenter :

  1. Lock applicatif sur le SI (table public.application, colonne migration_in_progress)
  2. Lock PostgreSQL sur le schéma (LOCK TABLE si_xxx.referencevalue IN EXCLUSIVE MODE)
  3. Politique RLS temporaire bloquant tout accès sauf userManager
  4. Timeout de 30 minutes maximum
  5. Notification aux utilisateurs connectés
  6. Rollback automatique avec release des locks en cas d'échec

Architecture des données

Configuration :

  • Table public.application : stockage configuration JSON complète
  • Champ configuration : JSONB avec structure { i18n, datadescription, hierarchicalnodes, tags, version }

Schéma SI dynamique (exemple si_acbb_ldt) :

  • Table referencevalue : données JSONB dans refvalues, liens dans refslinkedto
  • Index GIN par referencetype : authorization_{referencetype}_index_refvalues_index
  • Type composite requiredauthorizations : un champ ltree[] par referencetype
  • Fonctions : getauthorization(), isauthorized(), getnodes()

Éléments générés dynamiquement par configuration :

  • Index GIN spécifiques (un par ReferenceType)
  • Type composite requiredauthorizations
  • Fonctions PL/pgSQL (avec logique spécifique aux ReferenceTypes du SI)
  • Policies RLS

Évolutivité

Le système doit permettre :

  • Ajout de nouvelles règles par annotation @Rule Easy Rules
  • Définition de règles en YAML externalisé
  • Extension par DataTransformer personnalisés
  • Ajout de validateurs spécifiques par type de checker

Tickets liés

Phase 1 - Infrastructure

  • #XXX-1 : Setup JaVers pour comparaison de configurations
  • #XXX-2 : Setup Easy Rules et architecture du moteur
  • #XXX-3 : Modèle de données pour MigrationPlan et ConfigurationChange
  • #XXX-4 : Service de verrouillage de schéma SI

Phase 2 - Règles de migration (Niveau SAFE)

  • #XXX-5 : Règle ajout de ReferenceType
  • #XXX-6 : Règle ajout de component optionnel
  • #XXX-7 : Règle ajout d'index personnalisé
  • #XXX-8 : Règle modification i18n

Phase 3 - Règles de migration (Niveau TRANSFORMABLE)

  • #XXX-9 : Règle modification de checker type (compatible)
  • #XXX-10 : Règle modification required true->false
  • #XXX-11 : Règle renommage de component

Phase 4 - Règles de migration (Niveau BREAKING/FORBIDDEN)

  • #XXX-12 : Règle suppression de ReferenceType
  • #XXX-13 : Règle changement de ReferenceChecker.reftype
  • #XXX-14 : Règle modification required false->true

Phase 5 - Génération et exécution

  • #XXX-15 : Générateur SQL dynamique (index, types, functions)
  • #XXX-16 : Intégration Flyway pour migrations Java
  • #XXX-17 : Executor avec transaction et rollback

Phase 6 - Interface et monitoring

  • #XXX-18 : API REST pour déclenchement migration
  • #XXX-19 : Interface Vue.js de validation du MigrationPlan
  • #XXX-20 : Logs et monitoring des migrations

Estimation globale

  • Phase 1 : 5 jours
  • Phase 2 : 4 jours
  • Phase 3 : 6 jours
  • Phase 4 : 5 jours
  • Phase 5 : 7 jours
  • Phase 6 : 5 jours

Total : ~32 jours (6-7 semaines)

Critères d'acceptation Epic

  • Une mise à jour de configuration SAFE s'applique automatiquement sans intervention
  • Une mise à jour TRANSFORMABLE transforme correctement les données existantes
  • Une mise à jour BREAKING est bloquée avec message explicite
  • Le verrouillage du SI empêche tout accès concurrent pendant la migration
  • En cas d'erreur, rollback complet avec état initial restauré
  • Les logs permettent de tracer toutes les étapes de la migration
  • Documentation complète pour ajouter de nouvelles règles

Références techniques