# Versionnement Mojaloop â une proposition
Note : ce document est un brouillon vivant de proposition de versionnement au sein de Mojaloop. Une fois prĂȘt, il sera soumis au CCB pour approbation.
# Vue dâensemble
Lâobjectif est de produire une proposition qui garde le schĂ©ma de versionnement simple Ă utiliser et clair sur la compatibilitĂ©, tout en couvrant les dĂ©tails nĂ©cessaires Ă un Ă©cosystĂšme Mojaloop.
Objectif : Proposer une norme pour une nouvelle « Mojaloop Version », qui regroupe :
- Helm : versions des services individuels, versions des composants de supervision
- Versions dâAPI : FSPIOP API, Hub Operations / Admin API, Settlement API
- Versions de schémas internes : schéma de base de données et messagerie interne
# Stratégies de versionnement / contexte (revue de littérature)
Comment les systÚmes actuels gÚrent-ils le versionnement ? Aperçu rapide.
- La plupart des bonnes pratiques suivent le versionnement sémantique pour les API ; voir #1198 (opens new window)
# Approches de déploiement sans interruption avec Kubernetes [5]
Observations clés :
- pour permettre les retours arriĂšre, les services doivent ĂȘtre compatibles en avant et en arriĂšre. les versions dâapplication consĂ©cutives doivent ĂȘtre compatibles au niveau schĂ©ma
- « Ne jamais déployer de changements de schéma rupteurs », les séparer en plusieurs déploiements
Par exemple, Ă partir dâune table PERSON :
PK ID
NAME
ADDRESS_LINE_1
ADDRESS_LINE_2
ZIPCODE
COUNTRY
Et nous souhaitons la normaliser en deux tables PERSON et ADDRESS :
#person
PK ID
NAME
#address
PK ID
FK PERSON_ID
ADDRESS_LINE_1
ADDRESS_LINE_2
ZIPCODE
COUNTRY
Si ce changement Ă©tait fait en une seule migration, deux versions de lâapplication ne seraient pas compatibles. Les changements de schĂ©ma doivent ĂȘtre dĂ©coupĂ©s :
- Créer la table ADDRESS
- Lâapp utilise les donnĂ©es PERSON comme avant
- Déclencher une copie des données vers ADDRESS
- ADDRESS devient la « source de vérité »
- Lâapp utilise les donnĂ©es ADDRESS
- Déclencher une copie des nouveaux ajouts vers ADDRESS vers PERSON
- ArrĂȘter la copie des donnĂ©es
- Supprimer les colonnes superflues de PERSON
Cela signifie quâun seul changement de schĂ©ma de base de donnĂ©es nĂ©cessite plusieurs versions dâapplication et plusieurs dĂ©ploiements successifs.
- [5] note aussi la simplicitĂ© Kubernetes pour dĂ©ployer ce type de changement * dĂ©ploiements rolling upgrade * Astuce : sâassurer que le point de santĂ© attend la fin des migrations !
- Q : comment faire de grands changements qui touchent Ă la fois le schĂ©ma et lâAPI ? * cela semble difficile et exige beaucoup de coordination * si mal conçu, un seul changement de schĂ©ma pourrait exiger que tous les DFSP soient alignĂ©s * dâoĂč lâidĂ©e que la version dâAPI et la version de service devraient ĂȘtre indĂ©pendantes. On doit pouvoir dĂ©ployer une nouvelle version de service (avec migration) tout en supportant une ancienne version dâAPI
# Utiliser un registre de schémas pour les messages Kafka [6]
- [6] propose des approches comme un registre de schémas pour Kafka, par ex. Apache Avro (opens new window)
- Cela ajoute un niveau de « rigidité » aux messages produits et aide à imposer le versionnement
- Ajoute un composant « registre de schĂ©mas » qui garantit la conformitĂ© des messages. Cela nâimpose pas Ă lui seul le versionnement, mais renforce les garanties sur les formats.
# Compatibilité arriÚre et avant [3], [4]
- « Le principe de robustesse : ĂȘtre libĂ©ral dans ce que lâon accepte et conservateur dans ce que lâon envoie ». Pour les API, cela implique une certaine tolĂ©rance cĂŽtĂ© consommateurs. [3]
- Compatibilité arriÚre vs incompatibilité arriÚre [4] :
- En général, les ajouts sont considérés compatibles arriÚre
- Supprimer ou renommer est incompatible arriĂšre
- Câest souvent au cas par cas ; la doc de conception dâAPI Google (opens new window) aide Ă lister les cas.
# ĂcosystĂšme Mojaloop
En parlant de versionnement, il faut préciser que nous versionnons des interfaces pour différentes parties.
# Proposition
La section suivante décrit la proposition de versionnement.
# Une « Mojaloop Version »
Une Mojaloop Version x.y.z peut englober les versions des trois APIs (dĂ©tail ci-dessous). Dans x.y.z, « x » est la version majeure et « y » mineure, comme pour le standard FSPIOP ; « z » est le correctif ou une release avec le mĂȘme x.y ; pour simplifier, il faut regrouper tous les composants de lâĂ©cosystĂšme pour indiquer ce qui est inclus.
En pratique Mojaloop version x.y inclut
- Mojaloop FSPIOP API
- Maintenue par le CCB (Change Control Board)
- Format x.y
- Actuellement v1.0, v1.1 et v2.0 en pipeline
- Settlement API
- Maintenue par le CCB
- Format x.y
- Actuellement v1.1 et v2.0 en pipeline
- Admin / Operations API
- Maintenue par le CCB
- Format x.y
- Peut utiliser v1.0
- Helm
- Maintenu par la Design Authority
- Format x.y.z
- Versionnement basé sur PI (Program Increment) + Sprint.
Note : le versionnement PI + Sprint a du sens dans le cadre actuel des Program Increments Mojaloop, mais devra ĂȘtre revu plus tard.
- Regroupe des versions compatibles de services individuels
- Schémas internes
- Maintenus par la Design Authority
- Schéma DB x.y
- Schéma de messagerie interne (Kafka) x.y
| Mojaloop | x.y | ||
|---|---|---|---|
| Propriétaire / mainteneur | Format | Signification | |
| APIs | |||
| - FSPIOP API | CCB | x.y | Majeur.Mineur |
| - Settlement API | CCB | x.y | Majeur.Mineur |
| - Admin/Operations API | CCB | x.y | Majeur.Mineur |
| Helm | Design Authority | x.y.z | PI.Sprint.Incrément |
| Schémas internes | |||
| - Schéma DB | Design Authority | x.y | Majeur.Mineur |
| - Messagerie interne | Design Authority | x.y | Majeur.Mineur |
Par exemple : Mojaloop 1.0 inclut
- APIs
- FSPIOP API v1.0
- Settlements API v1.1
- Admin API v1.0
- Helm v9.1.0
- Versions des services individuels
- Versions des composants de supervision
- Schémas internes
- Schéma DB v1.0
- Version messagerie interne v1.0
| Mojaloop | v1.0 | ||
|---|---|---|---|
| Propriétaire / mainteneur | Version | ||
| APIs | |||
| - FSPIOP API | CCB | 1.0 | |
| - Settlement API | CCB | 1.1 | |
| - Admin/Operations API | CCB | 1.0 | |
| Helm | Design Authority | 9.1.0 | |
| Schémas internes | |||
| - Schéma DB | Design Authority | 1.0 | |
| - Messagerie interne | Design Authority | 1.0 |
# Avantages
- La stratĂ©gie privilĂ©gie la simplicitĂ©. Une version donnĂ©e â Mojaloop v1.0 â sert de rĂ©fĂ©rence commune aux trois APIs â FSPIOP, Settlements, Admin â ainsi quâĂ la version Helm qui regroupe des services compatibles dĂ©ployables ensemble. Avec cela, les versions de schĂ©ma DB et messagerie interne indiquent si des changements ont eu lieu depuis la release prĂ©cĂ©dente.
- Lâautre avantage, Ă©vident, est de rĂ©pondre aux besoins de toutes les parties prenantes, quâelles sâintĂ©ressent Ă une vue dâensemble ou au dĂ©tail. GrĂące Ă la nature des versions majeures et mineures, utilisateurs et adopteurs pourront plus aisĂ©ment apprĂ©hender les questions de compatibilitĂ©.
# Compatibilité
Comme dĂ©crit dans la section 3.3 de lâAPI Definition v1.0 (opens new window), la compatibilitĂ© arriĂšre est indiquĂ©e par la version majeure. Toutes les versions partageant la mĂȘme majeure doivent ĂȘtre compatibles ; des majeures diffĂ©rentes ne le seront probablement pas.
Note importante : les opérateurs de hub devront probablement supporter plusieurs versions de la FSPIOP API en parallÚle, car tous les participants ne peuvent pas monter de version simultanément.
# Décomposition de la « Mojaloop Version »
Cette section décompose la « Mojaloop Version » proposée et étaye la stratégie.
# APIs
La spec Mojaloop (opens new window) couvre déjà plusieurs choix de versionnement.
En pratique courante, plusieurs approches existent pour demander une version, y compris dans lâURL ; la spec le dĂ©finit dĂ©jĂ via lâextension HTML vendor : 3.3.4.1 Http Accept Header (opens new window)
Pour la nĂ©gociation de version, la spec indique quâen cas de version non prise en charge demandĂ©e par le client, une rĂ©ponse HTTP 406 peut ĂȘtre renvoyĂ©e avec un message dĂ©crivant les versions prises en charge. 3.3.4.3 Non-Acceptable Version Requested by Client (opens new window)
Autre bonne pratique : prĂ©ciser jusquâoĂč les clients peuvent cibler une version.
- En dĂ©veloppement, beaucoup dâAPIs permettent jusquâau niveau BUGFIX, ex. vX.X.X
- En production, souvent limité aux majeures seulement, ex. v1, v2
- ex. Google API Platform ne supporte que les majeures
- Avec les nouveautĂ©s possibles en v1.1 de lâAPI Mojaloop, on pourrait vouloir permettre MAJEURE et MINEURE, ex. vX.X. Ă Ă©viter en principe car les mineures doivent rester compatibles arriĂšre
Les participants sur la mĂȘme version MAJEURE de lâAPI doivent pouvoir interagir. Les majeures diffĂ©rentes ne le peuvent pas. Ex. un participant en v1.1 peut envoyer des transferts vers un autre en v1.0, mais pas vers un participant en v2.0.
# Helm
Cette section traite les interactions entre services Mojaloop dans un déploiement. Questions du type : une instance cent-ledger:v10.0.1 peut-elle parler à ml-api-adapter:v10.1.0 ? Et ml-api-adapter:v11.0.0 ? Ou comment cent-ledger:v10.0.1 et v10.1.0 accÚdent-ils à la base en parallÚle ?
Deux cas :
- Interactions avec lâĂ©tat persistĂ© â bases MySQL Percona
- Interactions entre services â Apache Kafka et (certaines) APIs internes
Il faut donc versionner :
- le schéma de base de données
- les messages dans Apache Kafka
- sâassurer que les bons services lisent les bons messages. Ex. mojaloop/ml-api-adapter:v10 .1.0 publie-t-il des messages Kafka que mojaloop/central-ledger:v10.0.1 comprend ?
- Q : si le format de message change de façon incompatible, comment éviter que des messages dans les flux Kafka soient consommés par les mauvais services ?
# Schémas internes
# Base de données
todo : à compléter ?
# Kafka / messagerie
Nous utilisons actuellement le protocole lime pour les formats Kafka : https://limeprotocol.org/
Voir aussi le readme mojaloop/central-services-stream pour le format des messages.
Le protocole lime prĂ©voit un champ type, qui supporte des dĂ©clarations de type MIME. On pourrait gĂ©rer les messages comme pour lâAPI (ex. application/vnd.specific+json). Versionner ainsi implique que les consommateurs soient compatibles en avant et en arriĂšre (versions consĂ©cutives compatibles schĂ©ma).
- Q. mettre la version dans le topic Kafka ?
- Ex. ml-api-adapter publie sur le topic prepare
- Avec versionnement, ml-api-adapter:v10.0.0 publie sur prepare_v10.0, et une nouvelle instance ml-api-adapter:v10.1.0 sur prepare_v10.1.
- les abonnés choisissent le(s) topic(s) ou les deux selon tolérance
- effets de bord possibles sur les performances
- Autre option : un « adaptateur » de messages dans le dĂ©ploiement. Si ml-api-adapter:v10.1.0 produit sur prepare_v10.1 sans central-ledger correspondant, un adaptateur sâabonne Ă prepare_v10.1, reformate en compatible arriĂšre, et republie sur prepare_v10.0.
Cela permettrait des changements de schéma incrémentaux pendant la montée de version des services.
En somme, je nâai pas trouvĂ© grand-chose sur ce sujet ; il faudra y revenir ultĂ©rieurement.
# Négociation de version
todo : @sam discuter de la stratégie de négociation de version
# Support long terme (LTS)
todo : discuter comment le LTS sâintĂšgre. Pas trop de dĂ©tail, plutĂŽt une esquisse.
Mentionner le (manque de) LTS actuel, le rythme des PI
# Annexe A : définitions
- service : Mojaloop suit une approche orientĂ©e microservices, oĂč une grande application est dĂ©composĂ©e en services plus petits. Dans ce contexte, Service dĂ©signe une application conteneurisĂ©e dans un dĂ©ploiement Mojaloop, typiquement un conteneur Docker dans un cluster Kubernetes. ex. mojaloop/central-ledger est le service central-ledger
- version de service : version du service. Ne suit pas encore le versionnement sémantique ; pourrait évoluer ex. mojaloop/central-ledger:v10.0.1. Voir le doc Versioning (opens new window).
- helm : gestionnaire de paquets pour Kubernetes. Souvent appelĂ© aussi « dĂ©ploiement ». Un dĂ©ploiement Helm exĂ©cute plusieurs services et PEUT exĂ©cuter plusieurs versions du mĂȘme service. On utilise aussi le dĂ©pĂŽt mojaloop/helm.
- version helm : version du chart packagé, ex. mojaloop/helm:v1.1.0
- interface : protocole par lequel un switch Mojaloop interagit avec lâextĂ©rieur â participants (DFSP), opĂ©rateurs de hub, administrateurs.
- api : interface de programmation â souvent le FSPIOP-API dĂ©fini ici (opens new window).
- version dâapi : version du FSPIOP-API, ex. FSPIOP-API v1. Ici, contrat entre le switch Mojaloop et les participants (DFSP) qui implĂ©mentent le FSPIOP-API
# Références
[1] LTS dans nodejs â bon exemple de stratĂ©gie LTS et communication. [2] RĂ©fĂ©rence Semantic Versioning [3] https://www.ben-morris.com/rest-apis-dont-need-a-versioning-strategy-they-need-a-change-strategy/ [4] https://cloud.google.com/apis/design/compatibility [5] Nicolas Frankel - Zero-downtime deployment with Kubernetes, Spring Boot and Flyway [6] Stackoverflow - Kafka Topic Message Versioning
