258 lines
7.8 KiB
Markdown
258 lines
7.8 KiB
Markdown
# 🔍 DIAGNOSTIC COMPLET - Kafka & WebSocket Temps Réel
|
|
|
|
**Date** : 28 janvier 2026
|
|
**Problème** : Messagerie, notifications et actualisations événementielles en temps réel ne fonctionnent pas avec Kafka
|
|
|
|
---
|
|
|
|
## 📋 RÉSUMÉ EXÉCUTIF
|
|
|
|
L'architecture temps réel utilise Kafka comme bus de messages entre les services métier et les WebSockets. Plusieurs problèmes critiques empêchent le bon fonctionnement :
|
|
|
|
1. ❌ **Heartbeat non démarré** côté Flutter
|
|
2. ⚠️ **Serializers Kafka manquants** (Quarkus auto-génère mais peut échouer)
|
|
3. ⚠️ **Configuration Kafka incomplète** (bootstrap servers, health checks)
|
|
4. ⚠️ **WebSocket paths** avec root-path `/afterwork`
|
|
5. ⚠️ **Bridges Kafka** peuvent ne pas démarrer si Kafka indisponible
|
|
|
|
---
|
|
|
|
## 🔴 PROBLÈMES CRITIQUES IDENTIFIÉS
|
|
|
|
### 1. Heartbeat Non Démarré (Flutter)
|
|
|
|
**Fichier** : `afterwork/lib/data/services/realtime_notification_service.dart`
|
|
|
|
**Problème** : La méthode `_startHeartbeat()` existe mais n'est **jamais appelée** après une connexion réussie.
|
|
|
|
**Ligne 88-101** : Après `_isConnected = true`, le heartbeat n'est pas démarré.
|
|
|
|
**Impact** :
|
|
- La connexion WebSocket peut timeout côté serveur
|
|
- Le statut de présence n'est pas maintenu
|
|
- Les notifications peuvent être perdues
|
|
|
|
**Solution** : Appeler `_startHeartbeat()` après la connexion réussie.
|
|
|
|
---
|
|
|
|
### 2. Serializers Kafka Non Explicites
|
|
|
|
**Fichier** : `application.properties`
|
|
|
|
**Problème** : Les serializers/deserializers sont omis avec le commentaire "Quarkus génère automatiquement". Cependant :
|
|
- Quarkus utilise Jackson pour sérialiser les DTOs
|
|
- Les DTOs doivent être correctement annotés
|
|
- En cas d'échec, les messages ne sont pas publiés dans Kafka
|
|
|
|
**Solution** : Ajouter explicitement les serializers Jackson ou vérifier que les DTOs sont sérialisables.
|
|
|
|
---
|
|
|
|
### 3. Configuration Kafka Bootstrap Servers
|
|
|
|
**Fichier** : `application.properties` et `application-prod.properties`
|
|
|
|
**Problème** :
|
|
- Production : `kafka-service.kafka.svc.cluster.local:9092` (Kubernetes DNS)
|
|
- Dev : `localhost:9092` (override dans `application-dev.properties`)
|
|
|
|
**Vérifications nécessaires** :
|
|
- Kafka est-il déployé en production ?
|
|
- Le service DNS `kafka-service.kafka.svc.cluster.local` est-il résolvable ?
|
|
- Les health checks Kafka sont-ils activés ?
|
|
|
|
**Solution** : Vérifier le déploiement Kafka et ajouter des health checks.
|
|
|
|
---
|
|
|
|
### 4. WebSocket Paths avec Root-Path
|
|
|
|
**Fichier** : `application-prod.properties`
|
|
|
|
**Problème** : `quarkus.http.root-path=/afterwork` est configuré.
|
|
|
|
**Impact potentiel** :
|
|
- Les WebSockets peuvent nécessiter le path complet : `wss://api.lions.dev/afterwork/notifications/{userId}`
|
|
- Le frontend Flutter utilise : `ws://{baseUrl}/notifications/{userId}`
|
|
|
|
**Vérification** : Tester si les WebSockets fonctionnent avec ou sans le root-path.
|
|
|
|
---
|
|
|
|
### 5. Bridges Kafka Peuvent Échouer Silencieusement
|
|
|
|
**Fichiers** : `NotificationKafkaBridge.java`, `ChatKafkaBridge.java`, etc.
|
|
|
|
**Problème** : Si Kafka n'est pas disponible au démarrage :
|
|
- Les bridges peuvent ne pas démarrer
|
|
- Aucune erreur visible si les exceptions sont catchées
|
|
- Les messages sont perdus sans notification
|
|
|
|
**Solution** : Ajouter des logs de démarrage et vérifier que les bridges sont actifs.
|
|
|
|
---
|
|
|
|
## 🟡 PROBLÈMES MOYENS
|
|
|
|
### 6. DTOs Événements Sans Annotations Jackson
|
|
|
|
**Fichiers** : `NotificationEvent.java`, `ChatMessageEvent.java`, etc.
|
|
|
|
**Problème** : Les DTOs utilisent Lombok mais peuvent manquer d'annotations Jackson pour la sérialisation JSON.
|
|
|
|
**Solution** : Vérifier que les DTOs sont correctement sérialisables avec Jackson.
|
|
|
|
---
|
|
|
|
### 7. Gestion d'Erreurs Kafka Silencieuse
|
|
|
|
**Fichiers** : `MessageService.java`, `EventService.java`, etc.
|
|
|
|
**Problème** : Les erreurs Kafka sont catchées et loggées mais ne remontent pas :
|
|
```java
|
|
} catch (Exception e) {
|
|
System.out.println("[ERROR] Erreur lors de la publication dans Kafka : " + e.getMessage());
|
|
// Ne pas bloquer l'envoi du message si Kafka échoue
|
|
}
|
|
```
|
|
|
|
**Impact** : Les messages sont sauvegardés en DB mais pas diffusés en temps réel, sans notification à l'utilisateur.
|
|
|
|
---
|
|
|
|
## ✅ CORRECTIONS À APPLIQUER
|
|
|
|
### Correction 1 : Démarrer le Heartbeat après Connexion
|
|
|
|
**Fichier** : `afterwork/lib/data/services/realtime_notification_service.dart`
|
|
|
|
```dart
|
|
_isConnected = true;
|
|
_startHeartbeat(); // ← AJOUTER CETTE LIGNE
|
|
if (!_isDisposed) {
|
|
notifyListeners();
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Correction 2 : Ajouter Serializers Kafka Explicites
|
|
|
|
**Fichier** : `application.properties`
|
|
|
|
Ajouter pour chaque topic outgoing :
|
|
```properties
|
|
mp.messaging.outgoing.notifications.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
|
|
mp.messaging.outgoing.chat-messages.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
|
|
mp.messaging.outgoing.reactions.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
|
|
mp.messaging.outgoing.presence.value.serializer=io.quarkus.kafka.client.serialization.JsonbSerializer
|
|
```
|
|
|
|
Et pour chaque topic incoming :
|
|
```properties
|
|
mp.messaging.incoming.kafka-notifications.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
|
|
mp.messaging.incoming.kafka-chat.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
|
|
mp.messaging.incoming.kafka-reactions.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
|
|
mp.messaging.incoming.kafka-presence.value.deserializer=io.quarkus.kafka.client.serialization.JsonbDeserializer
|
|
```
|
|
|
|
**Note** : Quarkus peut utiliser Jackson au lieu de Jsonb. Vérifier la dépendance dans `pom.xml`.
|
|
|
|
---
|
|
|
|
### Correction 3 : Vérifier les DTOs avec Annotations Jackson
|
|
|
|
**Fichiers** : Tous les DTOs d'événements
|
|
|
|
Ajouter si nécessaire :
|
|
```java
|
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
|
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
public class NotificationEvent {
|
|
@JsonProperty("userId")
|
|
private String userId;
|
|
// ...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Correction 4 : Ajouter Logs de Démarrage des Bridges
|
|
|
|
**Fichiers** : Tous les bridges Kafka
|
|
|
|
Ajouter dans chaque bridge :
|
|
```java
|
|
@PostConstruct
|
|
public void init() {
|
|
Log.info("[KAFKA-BRIDGE] Bridge démarré pour topic: notifications");
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Correction 5 : Améliorer la Gestion d'Erreurs Kafka
|
|
|
|
**Fichiers** : Services qui publient dans Kafka
|
|
|
|
Au lieu de :
|
|
```java
|
|
} catch (Exception e) {
|
|
System.out.println("[ERROR] Erreur Kafka");
|
|
}
|
|
```
|
|
|
|
Utiliser :
|
|
```java
|
|
} catch (Exception e) {
|
|
Log.error("[ERROR] Erreur publication Kafka", e);
|
|
// Optionnel: Notifier l'utilisateur ou retry
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🧪 TESTS DE VALIDATION
|
|
|
|
### Test 1 : Vérifier Connexion Kafka
|
|
```bash
|
|
# En production (Kubernetes)
|
|
kubectl exec -it kafka-pod -- kafka-console-consumer --bootstrap-server localhost:9092 --topic notifications --from-beginning
|
|
```
|
|
|
|
### Test 2 : Vérifier WebSocket
|
|
```javascript
|
|
// Dans la console navigateur
|
|
const ws = new WebSocket('wss://api.lions.dev/afterwork/notifications/{userId}');
|
|
ws.onopen = () => console.log('Connected');
|
|
ws.onmessage = (e) => console.log('Message:', e.data);
|
|
```
|
|
|
|
### Test 3 : Vérifier Heartbeat Flutter
|
|
- Ouvrir les logs Flutter
|
|
- Vérifier que des "Ping envoyé" apparaissent toutes les 30 secondes
|
|
|
|
---
|
|
|
|
## 📊 CHECKLIST DE VÉRIFICATION
|
|
|
|
- [ ] Kafka est déployé et accessible
|
|
- [ ] Les topics Kafka existent (`notifications`, `chat.messages`, `reactions`, `presence.updates`)
|
|
- [ ] Les bridges Kafka démarrent sans erreur
|
|
- [ ] Les WebSockets se connectent correctement
|
|
- [ ] Le heartbeat Flutter fonctionne
|
|
- [ ] Les messages sont publiés dans Kafka
|
|
- [ ] Les messages sont routés vers WebSocket
|
|
- [ ] Les clients reçoivent les notifications
|
|
|
|
---
|
|
|
|
## 🔗 RESSOURCES
|
|
|
|
- [Quarkus Reactive Messaging Kafka](https://quarkus.io/guides/kafka)
|
|
- [Quarkus WebSockets Next](https://quarkus.io/guides/websockets-next)
|
|
- [SmallRye Reactive Messaging](https://smallrye.io/smallrye-reactive-messaging/)
|