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:
@@ -12,6 +12,10 @@ import com.lions.dev.exception.UserNotFoundException;
|
||||
import com.lions.dev.repository.EventsRepository;
|
||||
import com.lions.dev.repository.FriendshipRepository;
|
||||
import com.lions.dev.repository.UsersRepository;
|
||||
import com.lions.dev.repository.EstablishmentRepository;
|
||||
import com.lions.dev.dto.events.NotificationEvent;
|
||||
import org.eclipse.microprofile.reactive.messaging.Channel;
|
||||
import org.eclipse.microprofile.reactive.messaging.Emitter;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -21,6 +25,10 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Service de gestion des événements.
|
||||
*
|
||||
* Version 2.0 - Architecture refactorée avec nommage standardisé.
|
||||
* Conforme à l'architecture de données AfterWork v2.0 (Ultra-Compétitive).
|
||||
*
|
||||
* Ce service contient la logique métier pour la création, récupération, mise à jour et suppression des événements.
|
||||
* Chaque méthode est loguée pour assurer une traçabilité exhaustive des actions effectuées.
|
||||
*/
|
||||
@@ -36,13 +44,20 @@ public class EventService {
|
||||
@Inject
|
||||
UsersRepository usersRepository;
|
||||
|
||||
@Inject
|
||||
EstablishmentRepository establishmentRepository; // v2.0
|
||||
|
||||
@Inject
|
||||
NotificationService notificationService;
|
||||
|
||||
@Inject
|
||||
@Channel("notifications")
|
||||
Emitter<NotificationEvent> notificationEmitter; // v2.0 - Publie dans Kafka
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(EventService.class);
|
||||
|
||||
/**
|
||||
* Crée un nouvel événement dans le système.
|
||||
* Crée un nouvel événement dans le système (v2.0).
|
||||
*
|
||||
* @param eventCreateRequestDTO Le DTO contenant les informations de l'événement à créer.
|
||||
* @param creator L'utilisateur créateur de l'événement.
|
||||
@@ -55,7 +70,18 @@ public class EventService {
|
||||
event.setDescription(eventCreateRequestDTO.getDescription());
|
||||
event.setStartDate(eventCreateRequestDTO.getStartDate());
|
||||
event.setEndDate(eventCreateRequestDTO.getEndDate());
|
||||
event.setLocation(eventCreateRequestDTO.getLocation());
|
||||
|
||||
// v2.0 - Établissement au lieu de location
|
||||
if (eventCreateRequestDTO.getEstablishmentId() != null) {
|
||||
com.lions.dev.entity.establishment.Establishment establishment =
|
||||
establishmentRepository.findById(eventCreateRequestDTO.getEstablishmentId());
|
||||
if (establishment != null) {
|
||||
event.setEstablishment(establishment);
|
||||
} else {
|
||||
logger.warn("[WARN] Établissement non trouvé avec l'ID : {}", eventCreateRequestDTO.getEstablishmentId());
|
||||
}
|
||||
}
|
||||
|
||||
event.setCategory(eventCreateRequestDTO.getCategory());
|
||||
event.setLink(eventCreateRequestDTO.getLink());
|
||||
event.setImageUrl(eventCreateRequestDTO.getImageUrl());
|
||||
@@ -63,6 +89,15 @@ public class EventService {
|
||||
event.setTags(eventCreateRequestDTO.getTags());
|
||||
event.setOrganizer(eventCreateRequestDTO.getOrganizer());
|
||||
event.setParticipationFee(eventCreateRequestDTO.getParticipationFee());
|
||||
|
||||
// v2.0 - Nouveaux champs
|
||||
if (eventCreateRequestDTO.getIsPrivate() != null) {
|
||||
event.setIsPrivate(eventCreateRequestDTO.getIsPrivate());
|
||||
}
|
||||
if (eventCreateRequestDTO.getWaitlistEnabled() != null) {
|
||||
event.setWaitlistEnabled(eventCreateRequestDTO.getWaitlistEnabled());
|
||||
}
|
||||
|
||||
event.setPrivacyRules(eventCreateRequestDTO.getPrivacyRules());
|
||||
event.setTransportInfo(eventCreateRequestDTO.getTransportInfo());
|
||||
event.setAccommodationInfo(eventCreateRequestDTO.getAccommodationInfo());
|
||||
@@ -70,16 +105,17 @@ public class EventService {
|
||||
event.setParkingInfo(eventCreateRequestDTO.getParkingInfo());
|
||||
event.setSecurityProtocol(eventCreateRequestDTO.getSecurityProtocol());
|
||||
event.setCreator(creator);
|
||||
event.setStatus("ouvert");
|
||||
event.setStatus("OPEN"); // v2.0 - Statut standardisé
|
||||
|
||||
// Persiste l'événement dans la base de données
|
||||
eventsRepository.persist(event);
|
||||
logger.info("[logger] Événement créé avec succès : {}", event.getTitle());
|
||||
|
||||
// Créer des notifications pour tous les amis
|
||||
// Créer des notifications pour tous les amis (v2.0 - avec Kafka)
|
||||
try {
|
||||
List<Friendship> friendships = friendshipRepository.findFriendsByUser(creator, 0, Integer.MAX_VALUE);
|
||||
String creatorName = creator.getPrenoms() + " " + creator.getNom();
|
||||
// v2.0 - Utiliser les nouveaux noms de champs
|
||||
String creatorName = creator.getFirstName() + " " + creator.getLastName();
|
||||
|
||||
for (Friendship friendship : friendships) {
|
||||
Users friend = friendship.getUser().equals(creator)
|
||||
@@ -89,6 +125,7 @@ public class EventService {
|
||||
String notificationTitle = "Nouvel événement de " + creatorName;
|
||||
String notificationMessage = creatorName + " a créé un nouvel événement : " + event.getTitle();
|
||||
|
||||
// Créer notification en base
|
||||
notificationService.createNotification(
|
||||
notificationTitle,
|
||||
notificationMessage,
|
||||
@@ -96,6 +133,28 @@ public class EventService {
|
||||
friend.getId(),
|
||||
event.getId()
|
||||
);
|
||||
|
||||
// TEMPS RÉEL: Publier dans Kafka (v2.0)
|
||||
try {
|
||||
java.util.Map<String, Object> notificationData = new java.util.HashMap<>();
|
||||
notificationData.put("eventId", event.getId().toString());
|
||||
notificationData.put("eventTitle", event.getTitle());
|
||||
notificationData.put("creatorId", creator.getId().toString());
|
||||
notificationData.put("creatorName", creatorName);
|
||||
notificationData.put("startDate", event.getStartDate().toString());
|
||||
|
||||
NotificationEvent kafkaEvent = new NotificationEvent(
|
||||
friend.getId().toString(), // userId destinataire
|
||||
"event_created",
|
||||
notificationData
|
||||
);
|
||||
|
||||
notificationEmitter.send(kafkaEvent);
|
||||
logger.debug("[logger] Événement event_created publié dans Kafka pour: {}", friend.getId());
|
||||
} catch (Exception kafkaEx) {
|
||||
logger.error("[ERROR] Erreur publication Kafka: {}", kafkaEx.getMessage());
|
||||
// Ne pas bloquer si Kafka échoue
|
||||
}
|
||||
}
|
||||
logger.info("[logger] Notifications créées pour {} ami(s)", friendships.size());
|
||||
} catch (Exception e) {
|
||||
@@ -209,12 +268,17 @@ public class EventService {
|
||||
throw new SecurityException("Vous n'avez pas les permissions pour modifier cet événement");
|
||||
}
|
||||
|
||||
// Mettre à jour les détails de l'événement
|
||||
// v2.0 - Mettre à jour les détails de l'événement
|
||||
existingEvent.setTitle(event.getTitle());
|
||||
existingEvent.setDescription(event.getDescription());
|
||||
existingEvent.setStartDate(event.getStartDate());
|
||||
existingEvent.setEndDate(event.getEndDate());
|
||||
existingEvent.setLocation(event.getLocation());
|
||||
|
||||
// v2.0 - Établissement au lieu de location
|
||||
if (event.getEstablishment() != null) {
|
||||
existingEvent.setEstablishment(event.getEstablishment());
|
||||
}
|
||||
|
||||
existingEvent.setCategory(event.getCategory());
|
||||
existingEvent.setLink(event.getLink());
|
||||
existingEvent.setImageUrl(event.getImageUrl());
|
||||
@@ -222,6 +286,15 @@ public class EventService {
|
||||
existingEvent.setTags(event.getTags());
|
||||
existingEvent.setOrganizer(event.getOrganizer());
|
||||
existingEvent.setParticipationFee(event.getParticipationFee());
|
||||
|
||||
// v2.0 - Nouveaux champs
|
||||
if (event.getIsPrivate() != null) {
|
||||
existingEvent.setIsPrivate(event.getIsPrivate());
|
||||
}
|
||||
if (event.getWaitlistEnabled() != null) {
|
||||
existingEvent.setWaitlistEnabled(event.getWaitlistEnabled());
|
||||
}
|
||||
|
||||
existingEvent.setPrivacyRules(event.getPrivacyRules());
|
||||
existingEvent.setTransportInfo(event.getTransportInfo());
|
||||
existingEvent.setAccommodationInfo(event.getAccommodationInfo());
|
||||
@@ -269,8 +342,22 @@ public class EventService {
|
||||
* @return La liste des événements auxquels l'utilisateur participe.
|
||||
*/
|
||||
public List<Events> findEventsByUser(Users user) {
|
||||
logger.info("[logger] Récupération des événements pour l'utilisateur avec l'ID : {}", user.getId());
|
||||
List<Events> events = eventsRepository.find("participants", user).list();
|
||||
return findEventsByUser(user, 0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les événements auxquels un utilisateur participe avec pagination.
|
||||
*
|
||||
* @param user L'utilisateur pour lequel récupérer les événements.
|
||||
* @param page Le numéro de la page (0-indexé)
|
||||
* @param size La taille de la page
|
||||
* @return La liste paginée des événements auxquels l'utilisateur participe.
|
||||
*/
|
||||
public List<Events> findEventsByUser(Users user, int page, int size) {
|
||||
logger.info("[logger] Récupération des événements pour l'utilisateur avec l'ID : {} (page: {}, size: {})", user.getId(), page, size);
|
||||
List<Events> events = eventsRepository.find("participants", user)
|
||||
.page(page, size)
|
||||
.list();
|
||||
logger.info("[logger] Nombre d'événements pour l'utilisateur avec l'ID {} : {}", user.getId(), events.size());
|
||||
return events;
|
||||
}
|
||||
@@ -372,7 +459,11 @@ public class EventService {
|
||||
*/
|
||||
public List<Events> recommendEventsForUser(Users user) {
|
||||
logger.info("[logger] Recommandation d'événements pour l'utilisateur : " + user.getEmail());
|
||||
List<Events> events = eventsRepository.find("category", user.getPreferredCategory()).list();
|
||||
// v2.0 - Utiliser preferences pour preferredCategory
|
||||
String preferredCategory = user.getPreferredCategory(); // Méthode qui utilise preferences JSONB
|
||||
List<Events> events = preferredCategory != null
|
||||
? eventsRepository.find("category", preferredCategory).list()
|
||||
: eventsRepository.findAll().list();
|
||||
logger.info("[logger] Nombre d'événements recommandés pour l'utilisateur : " + events.size());
|
||||
return events;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user