Claude [Sun, 17 May 2026 15:03:21 +0000 (15:03 +0000)]
refactor: Docker-Build auf bootBuildImage (Cloud Native Buildpacks) umstellen
Bisher baute Maven den Docker-Image via io.fabric8:docker-maven-plugin und
ein handgepflegtes Dockerfile. Gradle kopierte das JAR umständlich in ein
target/-Verzeichnis, damit dasselbe Dockerfile funktioniert (COPY target/*.jar).
Beide Build-Systeme nutzen jetzt bootBuildImage, das über Cloud Native
Buildpacks direkt aus dem Spring Boot Plugin heraus ein OCI-Image erzeugt:
Vorteile:
- Kein Dockerfile mehr nötig (und damit kein Kopier-Hack in Gradle)
- Beide Build-Systeme verwenden dieselbe Methode mit identischer Konfiguration
- Das erzeugte Image folgt automatisch Best Practices (non-root, layered JAR)
- io.fabric8:docker-maven-plugin und com.bmuschko.docker-remote-api entfallen
Claude [Sun, 17 May 2026 15:02:10 +0000 (15:02 +0000)]
fix: Projektname in settings.gradle korrigieren
Der Gradle-Projektname war auf 'spring-consumer' gesetzt, während die
Maven-Konfiguration das Artefakt 'nodlt' nennt. Dadurch hieß das JAR
'spring-consumer-<version>.jar' statt 'nodlt-<version>.jar', was zu
Inkonsistenzen zwischen Maven- und Gradle-Build führte.
Kai Moritz [Tue, 8 Apr 2025 05:32:28 +0000 (07:32 +0200)]
`fetch.max.wait` kann für den Consumer hier ausgeschaltet werden
* Der Consumer liest nur Nachrichten aus der Vergangenheit
* Daher bremst dieser Wert das Lesen ggf. nur aus, wenn der Consumer, so
wie hier in den Tests, sehr nah an der Gegenwart liest.
Kai Moritz [Sat, 21 Mar 2026 12:38:38 +0000 (13:38 +0100)]
`ApplicationTests` verwendet die echte MVC-Implementierung
* Der Test verwendet jetzt nicht mehr `@AutoconfigureMockMvc`.
* Statdessen wird `RANDOM_PORT` und das `TestRestTemplate` verwendet.
* Außerdem:
** Logging für den Zookeeper- und den Broker-Prozess unterdrückt.
** `ApplicationTests` überarbeitet/aufgeräumt.
Kai Moritz [Fri, 20 Mar 2026 14:26:21 +0000 (15:26 +0100)]
Consumer arbeitet nicht fortlaufend: `enable.auto.commit=false` gesetzt
- Das Speichern der Offset-Position ist nicht nötig:
- Der Consumer springt gezielt einzelne Offset-Positionen an und
pausiert, wenn er diese gelesen hat.
- Der Consumer arbeitet mit `assign()`, als erfolgt keine durch
"äußerliche" Ereignisse ausgelöste Neuzurodnung von Partitionen
während der Verarbeitung.
- Daher kann das Speichern der Offset-Positionen deaktiviert werden.
Kai Moritz [Fri, 22 May 2026 12:40:55 +0000 (12:40 +0000)]
fix: Gradle-Version an Maven-Version angleichen (1.0-SNAPSHOT)
Maven und Gradle hatten unterschiedliche Versionen (1.0-SNAPSHOT vs.
1.1-SNAPSHOT). Beide Build-Systeme sollen dieselbe Version liefern, daher
wird die Gradle-Version auf 1.0-SNAPSHOT korrigiert.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kai Moritz [Sun, 27 Oct 2024 21:08:53 +0000 (22:08 +0100)]
`ExampleConsumer` in eine Spring-Boot App umgebaut (ohne Spring Kafka)
* Consumerspezifische Properties werden in eigener nested Class verwaltet
** Dadurch wird der Code übersichtlicher, wenn spätere Implementierungen
* _sowohl_ als Consumer, _als auch_ als Producer agieren!
* Fix: `close()` muss noch vom `ExampleConsumer` aufgerufen werden
** Der Aufruf von `close()` löst die Abmeldung der Instanz bei dem
* GroupCoordinator aus.
** Dieser Vorgang sollte noch unter der Kontrolle des Anwendungscodes
* erfolgen!
** Wenn die Methode erst von Spring aufgerufen wird, werden dann ggf. noch
* Seiteneffekte ausgelöst, die dann noch im Kontext der Instanz laufen,
* obwohl diese eigentlich schon beendet wurde!
* Ungefangene Exceptions im `ExampleConsumer` lösen das Beenden der App aus
* Das Docker-Setup verwendet den `spring-producer`
** Die Konfiguration wurde außerdem so überarbeitet, dass der Producer
mehr Nachrichten verschickt (ca. 10 Nachrichten pro Sekunde) und diese
in Batches à ca. 6 Nachrichten verpackt.
* *Das Docker-Setup verwendet den ``juplo/simple-producer:1.0-SNAPSHOT``*
** Zu dem Zeitpunkt, zu dem der `juplo/simple-consumer:1.0-SNAPSHOT` in
dem Live-Coding in den `juplo/spring-consumer:1.1-SNAPSHOT` umgebaut
wird, existiert der `juplo/spring-producer:2.0-SNAPSHOT` noch nicht!
.dockerignore und .maven-dockerinclude gehören zum alten
Dockerfile/fabric8-basierten Build-Workflow und werden von
Jib bzw. bootBuildImage nicht benötigt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kai Moritz [Sat, 23 May 2026 06:55:54 +0000 (06:55 +0000)]
refactor: Dockerfile und manuelle Jar-Packaging-Konfiguration entfernen
Seit der Umstellung auf Jib ist das Dockerfile nicht mehr nötig.
maven-dependency-plugin und maven-jar-plugin-Konfiguration (Classpath-
Manifest) waren nur für den manuellen Docker-Build-Weg erforderlich.
Jib übernimmt das Packaging vollständig; mainClass ist nun explizit
in der Jib-Konfiguration gesetzt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kai Moritz [Fri, 22 May 2026 12:39:00 +0000 (12:39 +0000)]
refactor: Docker-Build von fabric8/bmuschko auf Jib umstellen
Maven nutzte das io.fabric8:docker-maven-plugin mit einem handgepflegten
Dockerfile. Gradle kopierte das JAR umständlich in ein target/-Verzeichnis,
damit dasselbe Dockerfile funktioniert (COPY target/*.jar).
Beide Build-Systeme nutzen jetzt Jib (com.google.cloud.tools:jib-maven-plugin
bzw. com.google.cloud.tools.jib), das direkt aus den compilierten Klassen
und Abhängigkeiten ein OCI-Image erzeugt:
Maven: mvn package (jib:dockerBuild ist an package-Phase gebunden)
Gradle: ./gradlew jibDockerBuild
Für den Registry-Push:
Maven: mvn jib:build
Gradle: ./gradlew jib
Vorteile:
- Kein Dockerfile mehr nötig (kein Kopier-Hack in Gradle)
- Beide Build-Systeme verwenden dieselbe Methode
- Optimiertes Layering (Abhängigkeiten in separaten Layern)
- Kein laufender Docker-Daemon für den Build nötig
Außerdem: gradle-git-properties Plugin hinzugefügt, analog zum
git-commit-id-plugin in Maven.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kai Moritz [Fri, 22 May 2026 12:38:32 +0000 (12:38 +0000)]
fix: Lombok in Maven korrekt als optional deklarieren
Lombok war mit <scope>compile</scope> deklariert, was dazu führt, dass
es als transitive Abhängigkeit weitergegeben wird. Da Lombok ein reines
Compile-Zeit-Tool (Annotation Processor) ist, muss es als <optional>true</optional>
markiert werden. Der Spring-Boot-Maven-Plugin schließt optionale
Abhängigkeiten automatisch aus dem fat-JAR aus.
Das Gradle-Setup ist in diesem Punkt bereits korrekt (compileOnly +
annotationProcessor).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kai Moritz [Sun, 15 Mar 2026 09:00:49 +0000 (10:00 +0100)]
Limits für die Definition des Service `producer` ergänzt
* Dadurch wird die Gefahr eingegrenzt, dass der Arbeitsplatz eines TN
überlastet wird.
* Dies ist einigen TN passiert, weil sie den `ExampleProducer` ohne
`Thread.sleep(500)` als Image gebaut haben.
* Wenn dieser dann unbedacht im Hintergrund weiterläuft, kann das den
Rechner schnell lahm legen...