I'm trying to create a Quarkus WebSocket server with some async workaround. I want to process the incoming messages asynchronously by publishing an event in the Vertx EventBus and then process them in a different 'service' class. At the same time, I want to be able to propagate the MDC context. Here is an example of what I'm trying to do, but so far the MDC context propagation is not working.
// WebSocket endpoint controller
@Slf4j
@ApplicationScoped
@ServerEndpoint(value = "/users/{userId}")
class UserWebSocketController {
private final WebsocketConnectionService websocketConnectionService;
private final Vertx vertx;
UserWebSocketController(WebsocketConnectionService websocketConnectionService, Vertx vertx) {
this.websocketConnectionService = websocketConnectionService;
this.vertx = vertx;
}
@OnOpen
void onOpen(Session session, @PathParam("userId") String userId) {
MDC.put("websocket.sessionId", session.getId());
MDC.put("user.id", userId);
log.info("New WebSocket Session opened.");
websocketConnectionService.addConnection(userId, session);
}
@OnMessage
void onMessage(Session session, String message, @PathParam("userId") String userId) {
// How do I get the same MDC context here?
//MDC.get("user.id") is null here
log.info("New message received.");
vertx.eventBus().send("websocket.message.new", message);
}
@OnClose
void onClose(Session session, @PathParam("userId") String userId) {
log.info("WebSocket Session closed.");
websocketConnectionService.removeSession(userId);
}
@OnError
void onError(Session session, @PathParam("userId") String userId, Throwable throwable) {
log.error("There was an error in the WebSocket Session.");
websocketConnectionService.removeSession(userId);
}
}
// Service class
@Slf4j
@ApplicationScoped
class UserService {
private final WebsocketConnectionService websocketConnectionService;
private final Vertx vertx;
UserService(WebsocketConnectionService websocketConnectionService, Vertx vertx) {
this.websocketConnectionService = websocketConnectionService;
this.vertx = vertx;
}
@ConsumeEvent("websocket.message.new")
Uni<Void> handleWebSocketMessages(String message) {
// How do I get the same MDC context here?
final var userId = MDC.get("user.id"); // this is null
log.info("'userId' exists in the MDC Context (userId=%s)".formatted(userId));
// do some business with the userId
return Uni.createFrom().voidItem();
}
}
Do you have any idea how can I make this context propagation work?