WebsocketRestEndpoint.java
/*
* The coLAB project
* Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.rest;
import ch.colabproject.colab.api.controller.WebsocketManager;
import ch.colabproject.colab.api.ws.channel.model.WebsocketChannel;
import ch.colabproject.colab.api.ws.message.WsSessionIdentifier;
import ch.colabproject.colab.generator.model.annotations.AdminResource;
import ch.colabproject.colab.generator.model.annotations.AuthenticationRequired;
import java.util.Map;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* API to manage subscription to {@link WebsocketChannel}.
* <p>
* <u>Note about un/subscriptions protocol:</u> The link between HttpSessionId (cookie) and
* websocket session id must be known. As the client has no access to its cookie (httpOnly cookie,
* for security concerns), the subscription is made through the REST methods defined here. Thus,
* both http session id and websocket session id are known at the same time.
*
* @author maxence
*/
@Path("websockets")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@AuthenticationRequired
public class WebsocketRestEndpoint {
/** logger */
private static final Logger logger = LoggerFactory.getLogger(WebsocketRestEndpoint.class);
/**
* Websocket business logic
*/
@Inject
private WebsocketManager wsManager;
/**
* Get the list of all occupied channels.
*
* @return list of all occupied channels:
*/
@GET
@AdminResource
public Map<String, Integer> getExistingChannels() {
logger.debug("Get all existing channels");
return wsManager.getExistingChannels();
}
/**
* Subscribe to the broadcast channel
*
* @param sessionId websocket session id
*/
@PUT
@Path("SubscribeToBroadcastChannel")
public void subscribeToBroadcastChannel(WsSessionIdentifier sessionId) {
logger.debug("Subscribe to broadcast channel with session id {}", sessionId);
wsManager.subscribeToBroadcastChannel(sessionId);
}
/**
* Unsubscribe from a the broadcast channel.
*
* @param sessionId websocket session id
*/
@PUT
@Path("UnSubscribeFromBroadcastChannel")
public void unsubscribeFromBroadcastChannel(WsSessionIdentifier sessionId) {
logger.debug("Unsubscribe from broadcast channel with session id {}", sessionId);
wsManager.unsubscribeFromBroadcastChannel(sessionId);
}
/**
* Subscribe to the currentUser channel
*
* @param sessionId websocket session id
*/
@PUT
@Path("SubscribeToUserChannel")
public void subscribeToUserChannel(WsSessionIdentifier sessionId) {
logger.debug("Subscribe to its own userchanell with session id {}", sessionId);
wsManager.subscribeToUserChannel(sessionId);
}
/**
* Unsubscribe from the currentUser channel
*
* @param sessionId websocket session id
*/
@PUT
@Path("UnsubscribeFromUserChannel")
public void unsubscribeFromUserChannel(WsSessionIdentifier sessionId) {
logger.debug("Unsubscribe from its own userchanell with session id {}", sessionId);
wsManager.unsubscribeFromUserChannel(sessionId);
}
/**
* Subscribe to a ProjectContent channel.
*
* @param projectId id of the project
* @param sessionId websocket session id
*/
@PUT
@Path("SubscribeToProjectChannel/{projectId: [0-9]+}")
public void subscribeToProjectChannel(
@PathParam("projectId") Long projectId,
WsSessionIdentifier sessionId
) {
logger.debug("Subscribe to project #{} channel with session id {}",
projectId, sessionId);
wsManager.subscribeToProjectChannel(sessionId, projectId);
}
/**
* Unsubscribe from a ProjectContent channel.
*
* @param projectId id of the project
* @param sessionId websocket session id
*/
@PUT
@Path("UnSubscribeFromProjectChannel/{projectId: [0-9]+}")
public void unsubscribeFromProjectChannel(
@PathParam("projectId") Long projectId,
WsSessionIdentifier sessionId
) {
logger.debug("Unsubscribe from project #{} channel with session id {}",
projectId, sessionId);
wsManager.unsubscribeFromProjectChannel(sessionId, projectId);
}
/**
* Subscribe to a BlockChannel.
*
* @param blockId id of the block
* @param sessionId websocket session id
*/
@PUT
@Path("SubscribeToBlockChannel/{blockId: [0-9]+}")
public void subscribeToBlockChannel(
@PathParam("blockId") Long blockId,
WsSessionIdentifier sessionId
) {
logger.debug("Subscribe to block #{} channel with session id {}", blockId, sessionId);
wsManager.subscribeToBlockChannel(sessionId, blockId);
}
/**
* Unsubscribe from a BlockContent channel.
*
* @param blockId id of the block
* @param sessionId websocket session id
*/
@PUT
@Path("UnSubscribeFromBlockChannel/{blockId: [0-9]+}")
public void unsubscribeFromBlockChannel(
@PathParam("blockId") Long blockId,
WsSessionIdentifier sessionId
) {
logger.debug("Unsubscribe from block #{} channel with session id {}", blockId, sessionId);
wsManager.unsubscribeFromBlockChannel(sessionId, blockId);
}
}