← Zur Uebersicht

Messaging-Redesign: JMS/IBM MQ -> Kafka (AMQ Streams)

Warum ueberhaupt wechseln

Oracle und DB2 bleiben laut 00-uebersicht.md bewusst unveraendert - reine Infrastruktur, kein Grund fuer einen Applikationsumbau. Bei IBM MQ ist die Entscheidung eine andere: auf ausdruecklichen Wunsch wird das Messaging mit dem Schritt nach OpenShift durch AMQ Streams (Kafka) ersetzt, das native OpenShift-Flaggschiff-Messaging (Strimzi-Operator). Das ist kein reiner Technologietausch wie bei den Datenbanken, weil JMS und Kafka konzeptionell unterschiedliche Werkzeuge sind - deshalb ein eigenes Dokument.

Warum der Code schon jetzt gegen Kafka entworfen wird, nicht erst gegen IBM MQ in Spring

Weil der Broker-Wechsel von Anfang an feststeht, waere es Wegwerfarbeit, zuerst @JmsListener/JmsTemplate gegen IBM MQ zu bauen und das kurz vor OpenShift wieder durch Kafka-Code zu ersetzen. Migrationsphase M3 baut deshalb direkt gegen Kafka.

JMS und Kafka sind keine 1:1-Entsprechung

JMS-Konzept Kafka-Entsprechung Unterschied
Queue (Point-to-Point) Topic mit einer Consumer-Group Kafka kennt keine Queues im JMS-Sinn; eine Consumer-Group auf einem Topic liefert aber dasselbe Verteilungsverhalten (jede Nachricht geht an genau eine Instanz der Gruppe)
Request/Reply (JMSReplyTo/JMSCorrelationID) zwei Topics + Correlation-Header, ReplyingKafkaTemplate Kafka hat kein eingebautes Antwort-Adressierungsmodell - muss explizit nachgebaut werden
Durable Topic Subscription + Message-Selektor Consumer-Group pro Abonnent, Filtern im Consumer-Code Kafka liefert jede Nachricht eines Topics an jede Consumer-Group - kein serverseitiges Vorfiltern vor der Zustellung wie bei JMS-Selektoren

Request/Reply: ClaimSubmissionClient -> ClaimIntakeMDB

Legacy: feste Antwort-Queue + JMSCorrelationID (siehe docs/30-jms-mq/02-request-reply.md).

Modern: zwei Topics, novaris.claims.submitted (Anfrage) und novaris.claims.result (Antwort) - siehe KafkaTopics in novaris-common-modern. Korrelation laeuft ueber den Kafka-Record-Header, den Spring Kafkas ReplyingKafkaTemplate automatisch setzt und beim Empfang wieder zuordnet - das bildet das Anfrage/Antwort-Gefuehl des Originals nach, ohne dass Kafka selbst das Konzept kennt.

Publish/Subscribe: PolicyEventPublisherBean -> zwei Notification-MDBs

Legacy: ein Topic, zwei durable Subscriptions mit unterschiedlichen Message-Selektoren (POLICY_ISSUED bzw. POLICY_ISSUED OR CLAIM_REGISTERED) - siehe docs/30-jms-mq/03-topics-und-selektoren.md.

Modern: ein Topic novaris.policy.events, zwei unabhaengige Consumer-Groups. Der eventType-Wert bleibt im JSON-Payload erhalten (PolicyEventMessage.getEventType()), aber das Filtern passiert jetzt im Consumer nach dem Empfang, nicht mehr serverseitig davor. Publish/Subscribe mit mehreren unabhaengigen Abonnenten ist dabei genau Kafkas ureigene Staerke - eher eine Vereinfachung als ein Verlust gegenueber dem JMS-Original.

DTOs: Serializable/ObjectMessage -> JSON

Die Legacy-DTOs (ClaimNotificationMessage usw.) sind bewusst als java.io.Serializable-Klassen dokumentiert - mit einer im Javadoc bereits vorausgesehenen Einschraenkung: harte Kopplung an dieselbe Java-Klasse auf Producer- und Consumer-Seite. Die modernen Gegenstuecke in novaris-common-modern sind Jackson-JSON-serialisierbar - genau die im Legacy-Javadoc angedeutete Loesung ("ein groesseres System wuerde eher zu einem schema-basierten Format tendieren").

Was noch aussteht (Migrationsphase M3)

⌂ Cockpit