feat: verbessere Onboarding-Workflow, verbessere mDNS-Discovery & ZNS-Import
Desktop CI — Headless Tests & Build / Compose Desktop — Tests (headless) & Build (push) Failing after 1m1s
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Successful in 6m29s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Successful in 6m14s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Failing after 1m17s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 1m48s

Signed-off-by: StefanMoCoAt <stefan.mo.co@gmail.com>
This commit is contained in:
2026-04-17 22:51:59 +02:00
parent 8f6044abe3
commit 88983f2b4e
22 changed files with 610 additions and 92 deletions
@@ -1,5 +1,7 @@
package at.mocode.frontend.core.network.discovery
import kotlinx.coroutines.flow.StateFlow
/**
* Modell für einen entdeckten Dienst im lokalen Netzwerk.
*/
@@ -16,6 +18,12 @@ data class DiscoveredService(
*/
interface NetworkDiscoveryService {
/**
* Ein StateFlow, der die aktuell entdeckten Dienste enthält.
* Ideal für reaktive UIs (Compose).
*/
val discoveredServices: StateFlow<List<DiscoveredService>>
/**
* Startet das Scannen nach verfügbaren Diensten im Netzwerk.
*/
fun startDiscovery()
@@ -32,7 +40,7 @@ interface NetworkDiscoveryService {
fun registerService(port: Int)
/**
* Gibt die Liste der aktuell entdeckten Dienste zurück.
* Gibt die Liste der aktuell entdeckten Dienste zurück (Snapshot).
*/
fun getDiscoveredServices(): List<DiscoveredService>
}
@@ -1,11 +1,14 @@
package at.mocode.frontend.core.network.discovery
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import java.net.InetAddress
import java.util.concurrent.ConcurrentHashMap
import javax.jmdns.JmDNS
import javax.jmdns.ServiceEvent
import javax.jmdns.ServiceInfo
import javax.jmdns.ServiceListener
import java.net.InetAddress
import java.util.concurrent.ConcurrentHashMap
/**
* JVM-spezifische Implementierung der Netzwerk-Discovery mittels JmDNS.
@@ -13,9 +16,12 @@ import java.util.concurrent.ConcurrentHashMap
class JmDnsDiscoveryService : NetworkDiscoveryService {
private var jmdns: JmDNS? = null
private val SERVICE_TYPE = "_meldestelle-biest._tcp.local."
private val SERVICE_TYPE = "_meldestelle._tcp.local."
private val discoveredServicesMap = ConcurrentHashMap<String, DiscoveredService>()
private val _discoveredServices = MutableStateFlow<List<DiscoveredService>>(emptyList())
override val discoveredServices: StateFlow<List<DiscoveredService>> = _discoveredServices.asStateFlow()
override fun startDiscovery() {
if (jmdns == null) {
jmdns = JmDNS.create(InetAddress.getLocalHost())
@@ -29,6 +35,7 @@ class JmDnsDiscoveryService : NetworkDiscoveryService {
override fun serviceRemoved(event: ServiceEvent) {
discoveredServicesMap.remove(event.name)
_discoveredServices.value = discoveredServicesMap.values.toList()
println("[Discovery] Service entfernt: ${event.name}")
}
@@ -41,6 +48,7 @@ class JmDnsDiscoveryService : NetworkDiscoveryService {
metadata = info.propertyNames.asSequence().associateWith { info.getPropertyString(it) }
)
discoveredServicesMap[event.name] = service
_discoveredServices.value = discoveredServicesMap.values.toList()
println("[Discovery] Service gefunden: ${service.name} @ ${service.host}:${service.port}")
}
})
@@ -50,6 +58,7 @@ class JmDnsDiscoveryService : NetworkDiscoveryService {
jmdns?.close()
jmdns = null
discoveredServicesMap.clear()
_discoveredServices.value = emptyList()
}
override fun registerService(port: Int) {