# 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 :

  1. Helm : versions des services individuels, versions des composants de supervision
  2. Versions d’API : FSPIOP API, Hub Operations / Admin API, Settlement API
  3. 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.

# 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 :

  1. Créer la table ADDRESS
    • L’app utilise les donnĂ©es PERSON comme avant
    • DĂ©clencher une copie des donnĂ©es vers ADDRESS
  2. 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
  3. ArrĂȘter la copie des donnĂ©es
  4. 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] :

# É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

  1. Mojaloop FSPIOP API
    • Maintenue par le CCB (Change Control Board)
    • Format x.y
    • Actuellement v1.0, v1.1 et v2.0 en pipeline
  2. Settlement API
    • Maintenue par le CCB
    • Format x.y
    • Actuellement v1.1 et v2.0 en pipeline
  3. Admin / Operations API
    • Maintenue par le CCB
    • Format x.y
    • Peut utiliser v1.0
  4. 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
  5. 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

  1. APIs
    • FSPIOP API v1.0
    • Settlements API v1.1
    • Admin API v1.0
  2. Helm v9.1.0
    • Versions des services individuels
    • Versions des composants de supervision
  3. 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

  1. 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.
  2. 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 :

  1. Interactions avec l’état persistĂ© — bases MySQL Percona
  2. 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