Aller au contenu

Ingénierie et intégration de systèmes

Connecter des systèmes hétérogènes sans créer un plat de spaghettis — topologies, patterns et stratégies d'intégration.


Le métier de l'intégration

L'intégration de systèmes est le travail qui consiste à faire fonctionner ensemble des systèmes qui n'ont pas été conçus pour ca. C'est un métier a part entière, souvent sous-estime et mal compris.

Jean-Pierre Meinadier, dans Le métier de l'intégration de systèmes, définit l'intégration comme la discipline qui transforme un ensemble de composants en un système cohérent. Ce n'est pas "brancher des APIs" — c'est concevoir les interactions, gérer les incoherences, absorber les pannes et maintenir la cohérence globale dans un environnement ou chaque composant évolue a son propre rythme.

Les UE GLG203/204 (architectures logicielles), NSY205 (conception de systèmes d'information) et NSY206 (ingénierie des systèmes d'information) du CNAM abordent cette discipline sous différents angles. Le point commun : l'intégration est le problème dominant des systèmes d'information d'entreprise. La majorité du budget IT ne va pas au développement de nouvelles fonctionnalités mais à la connexion et la maintenance de systèmes existants.

Pourquoi l'intégration est difficile :

  • Les systèmes a intégrer ont des modèles de données différents (semantique, format, granularité)
  • Ils ont des cycles de vie différents (disponibilité, versions, deprecations)
  • Ils ont des garanties différentes (cohérence, latence, débit)
  • Les équipes qui les gèrent ont des priorités différentes
  • Les contrats d'interface sont rarement documentes exhaustivement

Topologies d'intégration

La topologie d'intégration définit comment les systèmes sont connectes. Quatre modèles couvrent la quasi-totalité des cas.

Point-a-point

Chaque système se connecte directement à chaque autre système dont il a besoin.

graph TB
    A["ERP"] <-->|"API"| B["CRM"]
    A <-->|"fichier"| C["Comptabilite"]
    B <-->|"API"| D["Marketing"]
    A <-->|"API"| D
    C <-->|"fichier"| D
    B <-->|"API"| C

Problème : avec N systèmes, on a potentiellement N*(N-1)/2 connexions. A 5 systèmes, c'est 10 connexions. A 20 systèmes, c'est 190. Chaque nouvelle intégration touche potentiellement tous les systèmes existants. La complexité croit de façon quadratique.

Le point-à-point fonctionne pour 2-3 systèmes. Au-delà, il devient un plat de spaghettis impossible a maintenir et a debugger.

Hub-and-spoke

Un hub central géré toutes les integrations. Les systèmes communiquent uniquement avec le hub, jamais directement entre eux.

graph TB
    HUB["Hub\n(ESB / iPaaS)"]
    A["ERP"] --> HUB
    B["CRM"] --> HUB
    C["Comptabilite"] --> HUB
    D["Marketing"] --> HUB
    E["RH"] --> HUB
    HUB --> A
    HUB --> B
    HUB --> C
    HUB --> D
    HUB --> E

Le hub centralise la transformation des données, le routage des messages et la gestion des erreurs. C'est le modèle classique de l'ESB (Enterprise Service Bus) des années 2000-2010.

Avantages : complexité lineaire (N connexions au lieu de N^2), point central de monitoring et de logging. Inconvénients : le hub est un SPOF (single point of failure), il devient un goulet d'étranglement a fort volume, et il concentre la complexité dans un composant que tout le monde dépend.

Bus (Event Bus / Message Bus)

Les systèmes publient et consomment des messages via un bus partage. Le bus ne contient pas de logique métier — il transporte des messages.

graph TB
    subgraph Systems
        A["ERP"]
        B["CRM"]
        C["Comptabilite"]
        D["Marketing"]
    end
    BUS["Message Bus\n(Kafka / RabbitMQ)"]
    A -->|"publie"| BUS
    B -->|"publie"| BUS
    BUS -->|"consomme"| C
    BUS -->|"consomme"| D
    BUS -->|"consomme"| A
    BUS -->|"consomme"| B

La différence avec le hub-and-spoke : le bus ne transforme pas les messages, il les transporte. La logique de transformation est dans les systèmes ou dans des adaptateurs dédiés. Le bus est plus léger, plus scalable et moins fragile qu'un ESB.

Mesh (Service Mesh)

Chaque système communique directement avec les autres, mais via un proxy sidecar qui géré le routage, la sécurité, la résilience et l'observabilité.

graph LR
    subgraph "Service A"
        A["App A"]
        PA["Proxy A"]
        A --> PA
    end
    subgraph "Service B"
        B["App B"]
        PB["Proxy B"]
        B --> PB
    end
    subgraph "Service C"
        C["App C"]
        PC["Proxy C"]
        C --> PC
    end
    PA <-->|"mTLS"| PB
    PA <-->|"mTLS"| PC
    PB <-->|"mTLS"| PC
    CP["Control Plane"] -.->|"config"| PA
    CP -.->|"config"| PB
    CP -.->|"config"| PC

Le mesh est la topologie des architectures microservices modernes. Istio et Linkerd sont les implémentations les plus courantes. Le mesh déplacé la complexité d'intégration du code applicatif vers l'infrastructure.

Comparaison des topologies

Topologie Complexité Scalabilité SPOF Cas d'usage
Point-a-point O(N^2) Faible Non 2-3 systèmes, intégration simple
Hub-and-spoke O(N) Moyenne Oui (hub) ESB classique, integrations legacy
Bus O(N) Haute Non (distribué) Event-driven, systèmes hétérogènes
Mesh O(N) Haute Non (distribué) Microservices, cloud-native

Enterprise Intégration Patterns (EIP)

Les Enterprise Intégration Patterns, documentes par Gregor Hohpe et Bobby Woolf, sont un catalogue de solutions recurrentes pour l'intégration de systèmes. Ces patterns sont indépendants de la technologie — ils s'appliquent que le bus soit Kafka, RabbitMQ ou un MQ legacy.

Message Channel

Le canal par lequel les messages transitent. Un canal est une connexion logique entre un producteur et un ou plusieurs consommateurs.

Type de canal Comportement Exemple
Point-to-point Un seul consommateur reçoit le message Queue de tâches a traiter
Publish-subscribe Tous les abonnes reçoivent le message Notification d'un événement métier

Message Router

Un composant qui reçoit un message et le redirige vers un ou plusieurs canaux selon des règles.

Content-Based Router : le routage dépend du contenu du message.

graph LR
    IN["Message entrant"] --> R["Content-Based\nRouter"]
    R -->|"type = ORDER"| C1["Canal Orders"]
    R -->|"type = PAYMENT"| C2["Canal Payments"]
    R -->|"type = SHIPPING"| C3["Canal Shipping"]

Splitter : un message contenant plusieurs éléments est eclate en N messages individuels.

Aggregator : l'inverse du splitter — des messages individuels sont regroupes en un message composite.

Message Translator

Transforme un message d'un format a un autre. C'est le pattern le plus utilisé en intégration — chaque système a son propre modèle de données, et la traduction est nécessaire à chaque frontiere.

Systeme A (ERP) :
  { "article_code": "ABC", "qty": 5, "unit_price_ht": 10.00 }

Translator :
  article_code -> sku
  qty -> quantity
  unit_price_ht -> unitPrice (conversion HT -> TTC)

Systeme B (E-commerce) :
  { "sku": "ABC", "quantity": 5, "unitPrice": 12.00 }

Message Endpoint

Le composant qui connecte une application au système de messaging. C'est l'adaptateur entre le code applicatif et le bus de messages.

Pattern d'endpoint Description
Polling Consumer Le consommateur interroge périodiquement le canal
Event-Driven Consumer Le consommateur est notifie quand un message arrive
Competing Consumers Plusieurs instances du même consommateur se partagent la charge
Idempotent Receiver Le consommateur géré les doublons (at-least-once delivery)

Stratégies d'intégration

Au-delà des patterns individuels, quatre stratégies d'intégration définissent l'approche globale.

API-led intégration

Chaque système expose une API (REST, gRPC, GraphQL). Les integrations passent par ces APIs. C'est l'approche la plus courante pour les systèmes modernes.

graph TB
    subgraph "Experience APIs"
        WEB["Web API"]
        MOBILE["Mobile API"]
    end
    subgraph "Process APIs"
        ORDER["Order API"]
        PAYMENT["Payment API"]
    end
    subgraph "System APIs"
        ERP_API["ERP API"]
        CRM_API["CRM API"]
    end
    WEB --> ORDER
    MOBILE --> ORDER
    ORDER --> PAYMENT
    ORDER --> ERP_API
    PAYMENT --> CRM_API

L'approche API-led (popularisee par MuleSoft) organisé les APIs en trois couches :

  • System APIs — exposent les systèmes existants avec une API propre
  • Process APIs — orchestrent des processus métier en combinant des System APIs
  • Expérience APIs — adaptent les données au canal (web, mobile, partenaire)

Event-driven intégration

Les systèmes communiquent par événements via un bus de messages. Chaque système publie ce qui s'est passe et consomme les événements qui le concernent. C'est l'approche décrite dans le chapitre event-driven, appliquee à l'intégration inter-systèmes.

File-based intégration

Les systèmes échangent des fichiers (CSV, XML, JSON) via un répertoire partage, un SFTP ou un stockage objet (S3). C'est l'approche la plus ancienne et la plus repandue dans les grandes entreprises.

Avantage Inconvénient
Simple a mettre en place Latence élevée (batch)
Fonctionne avec n'importe quel système Pas de feedback en temps réel
Pas de couplage temporel Gestion des erreurs manuelle
Tolérant aux pannes Duplication et incoherence si mal géré

Le file-based intégration reste pertinent pour les batch de données volumineuses (import/export de catalogues, reporting comptable, synchronisation de référentiels).

Database-shared intégration

Plusieurs systèmes partagent la même base de données. Un système écrit, les autres lisent.

Anti-pattern dans la majorité des cas

Le partage de base de données crée un couplage fort entre systèmes. Un changement de schéma casse tous les systèmes qui lisent la base. C'est acceptable pour du reporting en lecture seule (vues materialisees), mais dangereux comme stratégie d'intégration principale.


Choisir sa stratégie

Critère API-led Event-driven File-based Database-shared
Latence Faible (ms) Moyenne (ms a s) Élevée (min a h) Faible (ms)
Couplage Temporel (synchrone) Faible (asynchrone) Aucun Fort (schéma)
Volume Moyen Élevé Très élevé Moyen
Complexité Moyenne Élevée Faible Faible
Fiabilité Dépend de la disponibilité Haute (bus resilient) Haute (fichiers persistants) Dépend de la base
Cas d'usage CRUD, orchestration Réactions, notifications Batch, export/import Reporting, BI

En pratique, un système d'information d'entreprise utilise plusieurs stratégies simultanément. Les APIs pour les interactions temps réel, les événements pour les notifications et les side effects, les fichiers pour les batch nocturnes, et occasionnellement des vues partagees pour le reporting.


Principes d'ingénierie des systèmes

L'ingénierie des systèmes (NSY205/NSY206) apporte un cadre méthodologique pour concevoir et intégrer des systèmes complexes.

Principe de séparation des preoccupations : chaque composant a une responsabilité claire. L'intégration ne doit pas diluer les responsabilités — un composant d'intégration route et transforme, il ne contient pas de logique métier.

Principe de substitution : un composant doit pouvoir être remplacé sans affecter le reste du système. Les interfaces d'intégration doivent être suffisamment abstraites pour absorber le remplacement d'un système (changer de CRM, migrer l'ERP).

Principe de testabilité : chaque point d'intégration doit pouvoir être teste en isolation. Les tests d'intégration end-to-end sont nécessaires mais pas suffisants — chaque connecteur, chaque transformation doit avoir ses propres tests unitaires.

Principe d'observabilité : chaque message qui traverse le système doit pouvoir être trace de bout en bout. Un correlation ID unique lie toutes les étapes du traitement. Sans observabilité, debugger une intégration multi-systèmes est un cauchemar.

L'intégration est un investissement continu

L'intégration n'est pas un projet ponctuel. C'est un investissement continu. Les systèmes evoluent, les APIs changent, les formats mutent. Prévoir du temps de maintenance pour les integrations au même titre que pour le code applicatif. Un budget de 20-30% du temps de développement pour la maintenance des integrations est un minimum realiste dans un SI d'entreprise.


Chapitre suivant : Connecter et stocker — flux, concurrence et persistance.