RabbitMQ mit CDI integrieren

Das folgende Code-Beispiele illustriert, wie das Konzept mit Hilfe von RabbitEasy, einer schlanken Open-Source-Bibliothek für RabbitMQ, umgesetzt wird:

Ein CDI Event wird folgendermaßen an einen Exchange gebunden:

public class MyEventBinder extends EventBinder {
    @Override
    protected void bindEvents() {
        bind(MyEvent.class)
            .toExchange("my.exchange")
            .withRoutingKey("my.routing.key");
    }
}

CDI Events können – wie gewohnt – gefeuert werden:

public class MyEventSource {
    @Inject Event eventControl;

    public void testEventFiring() {
 MyEvent event = new MyEvent();
        eventControl.fire(event);
    }
}

Ein CDI Event wird wie folgt an eine Queue gebunden:

public class MyEventBinder extends EventBinder {
    @Override
    protected void bindEvents() {
        bind(MyEvent.class).toQueue("my.queue");
    }
}

CDI Events werden – wie gewohnt – konsumiert:

public class MyEventObserver {
    public void testEventObserving(@Observes MyEvent event) {
        // Processing of the event
    }
}

Wie das Beispiel zeigt, ist die Broker-spezifische Konfiguration von der fachlichen Implementierung sauber getrennt. Im fachlichen Code ist nur CDI präsent, also pures Java EE. Doch die Lösung bietet neben sauberem Code auch noch weitere Vorteile:

  • Nutzung aller CDI Features, z.B. von Qualifiers
  • Austauschbarkeit der Event-Publizierung ohne Änderungen im fachlichen Code
  • Verwendung auch in Java SE möglich (z.B. mit Weld)
  • Einfache Prototypen ohne Message Broker Infrastruktur
  • Einfaches Testen des fachlichen Codes ohne Message Broker Infrastruktur

Die letzten beiden Punkte sind besonders erwähnenswert, da sie einen ganz konkreten geschäftlichen Nutzen bieten: In der frühen Phase der Entwicklung eines Projekts kann eine einfache Applikation entwickelt werden, dessen Module noch in der selben JVM „leben“, und die sich zunächst via CDI Events austauschen. In einer späteren Projektphase, wenn Produktivbetrieb in greifbare Nähe gerückt ist und Skalierbarkeit wichtig wird, können die Module getrennt und mehrfach deployed werden. Die vormals lokalen CDI Events können dann via RabbitMQ ausgetauscht werden. Dies ist möglich, ohne den Code aus dem Prototypen grundlegend anpassen zu müssen, sondern geschieht durch Ergänzungen an zentraler Stelle.

Das selbe Vorgehen lässt sich zum Testen der fachlichen Logik auch umkehren: Module, die via RabbitMQ CDI Events austauschen, können zum integrativen Testen der fachlichen Logik wieder lokal zusammengeführt werden. Durch simples Abhängigkeiten-Management (Maven, Gradle) kann die fachliche Logik in gewöhnlichen Unit-Tests getestet werden, ohne dafür eine Messaging-Infrastruktur zu benötigen. Dies wird wieder durch die natürliche Kopplung über CDI ermöglicht, und ohne dass dafür Hilfsmittel wie Mocks notwendig wären.

Zusammenfassend lässt sich sagen, dass der Ansatz eine elegante Integration von RabbitMQ in Java EE ermöglicht, ohne dass dabei wesentliche Kompromisse auf der einen oder der anderen Seite eingegangen werden müssen. Im Gegenteil: Es entstehen neue Synergien zwischen den Technologien, die sich vom Anfangsstadium bis zur Reife einer Applikation positiv auf die Entwicklung auswirken. Dabei bleibt die Interoperabilität mit Clients anderer Programmiersprachen unangetastet, da diese nach wie vor als Produzenten oder Konsumenten der gesendeten und empfangenen AMQP-Nachrichten auftreten können.

Das Ergebnis dieses Ansatzes ist die bereits genannte Bibliothek RabbitEasy, die unter der Apache-2.0-Lizenz entwickelt wird und auf GitHub zur Verfügung steht. Darüber hinaus findet sich dort ein Beispiel-Projekt, RabbitOrdering, das zur Veranschaulichung und Vertiefung des vorgestellten Ansatzes genutzt werden kann.

Christian Bick arbeitet als Software-Entwickler und beschäftigt sich mit unterschiedlichsten Aspekten von Web-Anwendungen. Bei zanox ist er dabei insbesondere für die Architektur-Domäne „Messaging mit RabbitMQ“ verantwortlich und veröffentlicht zu diesem Thema regelmäßig Beiträge in seinem Blog.
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.