feat: migration complète vers WebSockets Next + Kafka pour temps réel

- Migration de Jakarta WebSocket vers Quarkus WebSockets Next
- Implémentation de l'architecture Kafka pour événements temps réel
- Ajout des DTOs d'événements (NotificationEvent, ChatMessageEvent, ReactionEvent, PresenceEvent)
- Création des bridges Kafka → WebSocket (NotificationKafkaBridge, ChatKafkaBridge, ReactionKafkaBridge)
- Mise à jour des services pour publier dans Kafka au lieu d'appeler directement WebSocket
- Suppression des classes obsolètes (ChatWebSocket, NotificationWebSocket)
- Correction de l'injection des paramètres path dans WebSockets Next (utilisation de connection.pathParam)
- Ajout des migrations DB pour bookings, promotions, business hours, amenities, reviews
- Mise à jour de la configuration application.properties pour Kafka et WebSockets Next
- Mise à jour .gitignore pour ignorer les fichiers de logs
This commit is contained in:
dahoud
2026-01-21 13:46:16 +00:00
parent 7dd0969799
commit 93c63fd600
78 changed files with 5019 additions and 1113 deletions

View File

@@ -8,10 +8,15 @@ import com.lions.dev.exception.UserNotFoundException;
import com.lions.dev.repository.FriendshipRepository;
import com.lions.dev.repository.SocialPostRepository;
import com.lions.dev.repository.UsersRepository;
import com.lions.dev.dto.events.ReactionEvent;
import org.eclipse.microprofile.reactive.messaging.Channel;
import org.eclipse.microprofile.reactive.messaging.Emitter;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -38,6 +43,10 @@ public class SocialPostService {
@Inject
NotificationService notificationService;
@Inject
@Channel("reactions")
Emitter<ReactionEvent> reactionEmitter; // v2.0 - Publie dans Kafka
/**
* Récupère tous les posts avec pagination.
*
@@ -99,7 +108,8 @@ public class SocialPostService {
// Créer des notifications pour tous les amis
try {
List<Friendship> friendships = friendshipRepository.findFriendsByUser(user, 0, Integer.MAX_VALUE);
String userName = user.getPrenoms() + " " + user.getNom();
// v2.0 - Utiliser les nouveaux noms de champs
String userName = user.getFirstName() + " " + user.getLastName();
for (Friendship friendship : friendships) {
Users friend = friendship.getUser().equals(user)
@@ -208,11 +218,12 @@ public class SocialPostService {
* Like un post (incrémente le compteur de likes).
*
* @param postId L'ID du post
* @param userId L'ID de l'utilisateur qui like (v2.0)
* @return Le post mis à jour
*/
@Transactional
public SocialPost likePost(UUID postId) {
System.out.println("[LOG] Like du post ID : " + postId);
public SocialPost likePost(UUID postId, UUID userId) {
System.out.println("[LOG] Like du post ID : " + postId + " par utilisateur : " + userId);
SocialPost post = socialPostRepository.findById(postId);
if (post == null) {
@@ -222,6 +233,31 @@ public class SocialPostService {
post.incrementLikes();
socialPostRepository.persist(post);
// TEMPS RÉEL: Publier dans Kafka (v2.0)
try {
Map<String, Object> reactionData = new HashMap<>();
reactionData.put("ownerId", post.getUser().getId().toString()); // Propriétaire du post
reactionData.put("likesCount", post.getLikesCount());
reactionData.put("postTitle", post.getContent().length() > 50
? post.getContent().substring(0, 50) + "..."
: post.getContent());
ReactionEvent event = new ReactionEvent(
postId.toString(), // targetId
"post", // targetType
userId.toString(), // userId qui réagit
"like", // reactionType
reactionData
);
reactionEmitter.send(event);
System.out.println("[LOG] Réaction like publiée dans Kafka pour post: " + postId);
} catch (Exception e) {
System.out.println("[ERROR] Erreur publication Kafka: " + e.getMessage());
// Ne pas bloquer le like si Kafka échoue
}
return post;
}
@@ -229,11 +265,13 @@ public class SocialPostService {
* Ajoute un commentaire à un post (incrémente le compteur de commentaires).
*
* @param postId L'ID du post
* @param userId L'ID de l'utilisateur qui commente (v2.0)
* @param commentContent Le contenu du commentaire (v2.0)
* @return Le post mis à jour
*/
@Transactional
public SocialPost addComment(UUID postId) {
System.out.println("[LOG] Ajout de commentaire au post ID : " + postId);
public SocialPost addComment(UUID postId, UUID userId, String commentContent) {
System.out.println("[LOG] Ajout de commentaire au post ID : " + postId + " par utilisateur : " + userId);
SocialPost post = socialPostRepository.findById(postId);
if (post == null) {
@@ -243,6 +281,35 @@ public class SocialPostService {
post.incrementComments();
socialPostRepository.persist(post);
// TEMPS RÉEL: Publier dans Kafka (v2.0)
try {
Users commenter = usersRepository.findById(userId);
Map<String, Object> reactionData = new HashMap<>();
reactionData.put("ownerId", post.getUser().getId().toString()); // Propriétaire du post
reactionData.put("commentsCount", post.getCommentsCount());
reactionData.put("commentContent", commentContent != null && commentContent.length() > 100
? commentContent.substring(0, 100) + "..."
: commentContent);
reactionData.put("commenterName", commenter != null
? commenter.getFirstName() + " " + commenter.getLastName()
: "Utilisateur");
ReactionEvent event = new ReactionEvent(
postId.toString(), // targetId
"post", // targetType
userId.toString(), // userId qui commente
"comment", // reactionType
reactionData
);
reactionEmitter.send(event);
System.out.println("[LOG] Réaction comment publiée dans Kafka pour post: " + postId);
} catch (Exception e) {
System.out.println("[ERROR] Erreur publication Kafka: " + e.getMessage());
// Ne pas bloquer le commentaire si Kafka échoue
}
return post;
}
@@ -250,11 +317,12 @@ public class SocialPostService {
* Partage un post (incrémente le compteur de partages).
*
* @param postId L'ID du post
* @param userId L'ID de l'utilisateur qui partage (v2.0)
* @return Le post mis à jour
*/
@Transactional
public SocialPost sharePost(UUID postId) {
System.out.println("[LOG] Partage du post ID : " + postId);
public SocialPost sharePost(UUID postId, UUID userId) {
System.out.println("[LOG] Partage du post ID : " + postId + " par utilisateur : " + userId);
SocialPost post = socialPostRepository.findById(postId);
if (post == null) {
@@ -264,6 +332,28 @@ public class SocialPostService {
post.incrementShares();
socialPostRepository.persist(post);
// TEMPS RÉEL: Publier dans Kafka (v2.0)
try {
Map<String, Object> reactionData = new HashMap<>();
reactionData.put("ownerId", post.getUser().getId().toString()); // Propriétaire du post
reactionData.put("sharesCount", post.getSharesCount());
ReactionEvent event = new ReactionEvent(
postId.toString(), // targetId
"post", // targetType
userId.toString(), // userId qui partage
"share", // reactionType
reactionData
);
reactionEmitter.send(event);
System.out.println("[LOG] Réaction share publiée dans Kafka pour post: " + postId);
} catch (Exception e) {
System.out.println("[ERROR] Erreur publication Kafka: " + e.getMessage());
// Ne pas bloquer le partage si Kafka échoue
}
return post;
}