State Machine (cycle de vie EDI)
L'automate fini explicite — états nommés, transitions gardées, journal complet — qui rend traçable et auditable la vie d'un message EDI.
Problème
Un INVOIC arrive à 10h00, traverse cinq composants (parser, validator, enricher, router, sender), peut être ack par l'ERP à 14h30, rejeté à 15h00, retraité à 16h00, archivé à 17h00. Si l'état est implicite — éparpillé dans des champs DB de plusieurs services, ou dans des logs — l'opérateur support EDI ne peut pas répondre à « où est ma facture ? ». Pire : un bug fait sauter une étape (l'ERP ack avant qu'on ait routé), et on découvre deux semaines plus tard que des factures sont en attente sans transition possible.
Forces
- Le cycle de vie EDI est complexe. Six à dix états selon les besoins (réception, validation, enrichissement, routage, ack, archivage).
- Les transitions sont contraintes. On ne passe pas de [Received] à [Archived] sans valider, enrichir, livrer.
- L'auditabilité est exigée. Conformité fiscale, RGPD, SLA partenaire — il faut prouver chaque transition.
- Les états d'erreur sont des états réels. Pas des exceptions à logger, mais des états dans lesquels le message peut rester quelques jours en attente d'action humaine.
- L'aspect temporel. Certaines transitions doivent se produire dans un délai (CONTRL sous 24h, ack ERP sous 4h).
Solution
Modéliser le cycle de vie comme une machine à états finie explicite avec : états nommés, transitions autorisées (DAG), gardes (conditions d'entrée), actions (effets de transition), événements de sortie (Domain Events émis). Le state machine est persisté : chaque message a son enregistrement avec état courant, historique, timestamps. La transition est atomique avec l'effet métier (via Outbox). Implémentations : tables d'état + verrou optimiste, ou workflow engine (Camunda, Temporal, AWS Step Functions, Apache Airflow pour batch). Liens forts avec Process Manager et Saga Orchestration.
Cycle de vie INVOIC entrant :
[Received] ─ message AS2 / AS4 arrivé
│
syntactic ok
▼
[SyntacticallyValid] ─ CONTRL positif envoyé
│
semantic ok
▼
[SemanticallyValid] ─ EN 16931 OK
│
business ok
▼
[BusinessValid] ─ règles métier OK
│
enriched
▼
[Enriched] ─ référentiels résolus
│
routed
▼
[Routed] ─ publié sur Kafka edi.invoices
│
acked by ERP
▼
[AckedByERP] ─ ERP a accusé réception
│
processed
▼
[Processed] ─ comptabilisé + payé
│
▼
[Archived] ─ stocké 10 ans S3 Object Lock
États d'erreur (transitions latérales) :
- [SyntacticallyInvalid] ← CONTRL négatif, DLC technique
- [SemanticallyInvalid] ← APERAK, DLC sémantique
- [BusinessRejected] ← APERAK + workflow business
- [EnrichmentFailed] ← retry ou degraded
- [RoutingFailed] ← retry
- [ErpRejected] ← exception flow
Implémentation EDI
Cas concret : hub EDI Java avec Spring State Machine ou Akka
FSM, ou workflow Temporal. Chaque INVOIC reçu a une rangée DB :
{ messageId, state: 'Received', history: [{state, at, by}], lastActivityAt }.
Le parser EDIFACT émet un événement SyntacticallyValid,
la state machine vérifie la garde (« state == 'Received' »)
et transitionne à SyntacticallyValid. Tentative de
sauter une étape : rejetée. Si le validator échoue à l'étape
business, transition à BusinessRejected, émission d'un
APERAK au partenaire, déclenchement d'un workflow opérateur. Le
dashboard ops montre la répartition : « 120 factures
Received, 5 BusinessRejected, 2 EnrichmentFailed ». Le
support répond « Votre facture INV-1234 est en état Enriched
depuis 10h32, prochaine étape routage ». Côté audit fiscal
français : la trace d'état remplace les logs pour prouver
qu'aucun INVOIC déposé n'a échappé à l'archivage. Outils :
Temporal (Cadence forkée par Uber) industrialise ce pattern à
grande échelle ; BPMN 2.0 dans Camunda offre une modélisation
visuelle.
Anti-patterns
- État implicite éparpillé. Champs
is_valid,is_enriched,is_ackeddans plusieurs tables : aucune cohérence transactionnelle. - Transitions non gardées. Un service peut directement passer de Received à Archived : le pattern est neutralisé.
- State machine en mémoire. Crash → état perdu → message en limbe.
- Trop d'états. 30 états microscopiques (parser-1, parser-2, parser-3) : ingérable. Garder un niveau de granularité métier-signifiant.
- Pas d'état d'erreur. Les erreurs traitées comme exceptions hors-machine : invisibles dans le dashboard, perdus dans les logs.
- State machine sans timers. Pas de détection des messages bloqués : on découvre 1 mois plus tard.
Patterns liés
- Process Manager — pattern parent EIP, état explicite de processus longs.
- Saga Orchestration — variante avec compensations.
- Process Engine — runtime BPMN/workflow qui exécute la state machine.
- Event Sourcing — l'historique des transitions peut être conservé comme événements.
- Message History — la trace des composants traversés.
- Validation Pipeline — les états Syntactically/Semantically/BusinessValid sortent du pipeline.
Sources
- Camunda — BPMN State Machine. Documentation et best practices pour modéliser un cycle de vie EDI en BPMN 2.0. docs.camunda.io — State Machine
- Temporal — Workflow as state machine. Implémentation moderne en code, fork Uber Cadence. docs.temporal.io
- Spring State Machine. Implémentation Java lightweight. spring.io — Statemachine
- UML State Machine spec (OMG). La théorie formelle Harel/UML. omg.org — UML
- Hohpe G., Woolf B. — Enterprise Integration Patterns, Addison-Wesley 2003. Process Manager (§312) — le pattern parent. enterpriseintegrationpatterns.com — Process Manager
- AWS Step Functions — Workflow Studio. Implémentation managée d'un state machine de production. aws.amazon.com — Step Functions