proctoring refactoring
This commit is contained in:
parent
3f2923da8f
commit
89ebf4da4b
12 changed files with 217 additions and 218 deletions
|
@ -15,7 +15,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class SEBProctoringConnectionData {
|
public class SEBProctoringConnection {
|
||||||
|
|
||||||
public static final String ATTR_CONNECTION_TOKEN = "connectionToken";
|
public static final String ATTR_CONNECTION_TOKEN = "connectionToken";
|
||||||
public static final String ATTR_SERVER_HOST = "serverHost";
|
public static final String ATTR_SERVER_HOST = "serverHost";
|
||||||
|
@ -47,7 +47,7 @@ public class SEBProctoringConnectionData {
|
||||||
public final String accessToken;
|
public final String accessToken;
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public SEBProctoringConnectionData(
|
public SEBProctoringConnection(
|
||||||
@JsonProperty(ProctoringSettings.ATTR_SERVER_TYPE) final ProctoringServerType proctoringServerType,
|
@JsonProperty(ProctoringSettings.ATTR_SERVER_TYPE) final ProctoringServerType proctoringServerType,
|
||||||
@JsonProperty(ATTR_CONNECTION_TOKEN) final String connectionToken,
|
@JsonProperty(ATTR_CONNECTION_TOKEN) final String connectionToken,
|
||||||
@JsonProperty(ATTR_SERVER_HOST) final String serverHost,
|
@JsonProperty(ATTR_SERVER_HOST) final String serverHost,
|
|
@ -32,7 +32,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
|
||||||
|
@ -455,12 +455,12 @@ public class MonitoringClientConnection implements TemplateComposer {
|
||||||
|
|
||||||
if (roomOptional.isPresent()) {
|
if (roomOptional.isPresent()) {
|
||||||
final RemoteProctoringRoom room = roomOptional.get();
|
final RemoteProctoringRoom room = roomOptional.get();
|
||||||
final SEBProctoringConnectionData proctoringConnectionData = this.pageService
|
final SEBProctoringConnection proctoringConnectionData = this.pageService
|
||||||
.getRestService()
|
.getRestService()
|
||||||
.getBuilder(GetProctorRoomConnectionData.class)
|
.getBuilder(GetProctorRoomConnectionData.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(proctoringSettings.examId))
|
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(proctoringSettings.examId))
|
||||||
.withQueryParam(SEBProctoringConnectionData.ATTR_ROOM_NAME, room.name)
|
.withQueryParam(SEBProctoringConnection.ATTR_ROOM_NAME, room.name)
|
||||||
.withQueryParam(SEBProctoringConnectionData.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
|
.withQueryParam(SEBProctoringConnection.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
|
||||||
.call()
|
.call()
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
|
@ -499,7 +499,7 @@ public class MonitoringClientConnection implements TemplateComposer {
|
||||||
.getProctoringGUIService();
|
.getProctoringGUIService();
|
||||||
|
|
||||||
if (!proctoringGUIService.hasRoom(roomName)) {
|
if (!proctoringGUIService.hasRoom(roomName)) {
|
||||||
final SEBProctoringConnectionData proctoringConnectionData = proctoringGUIService
|
final SEBProctoringConnection proctoringConnectionData = proctoringGUIService
|
||||||
.registerNewSingleProcotringRoom(
|
.registerNewSingleProcotringRoom(
|
||||||
examId,
|
examId,
|
||||||
roomName,
|
roomName,
|
||||||
|
|
|
@ -44,7 +44,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||||
|
@ -445,7 +445,7 @@ public class MonitoringRunningExam implements TemplateComposer {
|
||||||
String activeAllRoomName = proctoringGUIService.getTownhallRoom(examId.modelId);
|
String activeAllRoomName = proctoringGUIService.getTownhallRoom(examId.modelId);
|
||||||
|
|
||||||
if (activeAllRoomName == null) {
|
if (activeAllRoomName == null) {
|
||||||
final SEBProctoringConnectionData proctoringConnectionData = proctoringGUIService
|
final SEBProctoringConnection proctoringConnectionData = proctoringGUIService
|
||||||
.registerTownhallRoom(
|
.registerTownhallRoom(
|
||||||
examId.modelId,
|
examId.modelId,
|
||||||
this.pageService.getI18nSupport().getText(EXAM_ROOM_NAME))
|
this.pageService.getI18nSupport().getText(EXAM_ROOM_NAME))
|
||||||
|
@ -642,12 +642,12 @@ public class MonitoringRunningExam implements TemplateComposer {
|
||||||
final RemoteProctoringRoom room,
|
final RemoteProctoringRoom room,
|
||||||
final PageAction action) {
|
final PageAction action) {
|
||||||
|
|
||||||
final SEBProctoringConnectionData proctoringConnectionData = this.pageService
|
final SEBProctoringConnection proctoringConnectionData = this.pageService
|
||||||
.getRestService()
|
.getRestService()
|
||||||
.getBuilder(GetProctorRoomConnectionData.class)
|
.getBuilder(GetProctorRoomConnectionData.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(proctoringSettings.examId))
|
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(proctoringSettings.examId))
|
||||||
.withQueryParam(SEBProctoringConnectionData.ATTR_ROOM_NAME, room.name)
|
.withQueryParam(SEBProctoringConnection.ATTR_ROOM_NAME, room.name)
|
||||||
.withQueryParam(SEBProctoringConnectionData.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
|
.withQueryParam(SEBProctoringConnection.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
|
||||||
.call()
|
.call()
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
|
|
|
@ -17,20 +17,20 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class ActivateTownhallRoom extends RestCall<SEBProctoringConnectionData> {
|
public class ActivateTownhallRoom extends RestCall<SEBProctoringConnection> {
|
||||||
|
|
||||||
public ActivateTownhallRoom() {
|
public ActivateTownhallRoom() {
|
||||||
super(new TypeKey<>(
|
super(new TypeKey<>(
|
||||||
CallType.UNDEFINED,
|
CallType.UNDEFINED,
|
||||||
EntityType.EXAM_PROCTOR_DATA,
|
EntityType.EXAM_PROCTOR_DATA,
|
||||||
new TypeReference<SEBProctoringConnectionData>() {
|
new TypeReference<SEBProctoringConnection>() {
|
||||||
}),
|
}),
|
||||||
HttpMethod.POST,
|
HttpMethod.POST,
|
||||||
MediaType.APPLICATION_FORM_URLENCODED,
|
MediaType.APPLICATION_FORM_URLENCODED,
|
||||||
|
|
|
@ -17,20 +17,20 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class GetProctorRoomConnectionData extends RestCall<SEBProctoringConnectionData> {
|
public class GetProctorRoomConnectionData extends RestCall<SEBProctoringConnection> {
|
||||||
|
|
||||||
public GetProctorRoomConnectionData() {
|
public GetProctorRoomConnectionData() {
|
||||||
super(new TypeKey<>(
|
super(new TypeKey<>(
|
||||||
CallType.GET_SINGLE,
|
CallType.GET_SINGLE,
|
||||||
EntityType.EXAM_PROCTOR_DATA,
|
EntityType.EXAM_PROCTOR_DATA,
|
||||||
new TypeReference<SEBProctoringConnectionData>() {
|
new TypeReference<SEBProctoringConnection>() {
|
||||||
}),
|
}),
|
||||||
HttpMethod.GET,
|
HttpMethod.GET,
|
||||||
MediaType.APPLICATION_FORM_URLENCODED,
|
MediaType.APPLICATION_FORM_URLENCODED,
|
||||||
|
|
|
@ -17,20 +17,20 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
@GuiProfile
|
@GuiProfile
|
||||||
public class SendJoinRemoteProctoringRoom extends RestCall<SEBProctoringConnectionData> {
|
public class SendJoinRemoteProctoringRoom extends RestCall<SEBProctoringConnection> {
|
||||||
|
|
||||||
public SendJoinRemoteProctoringRoom() {
|
public SendJoinRemoteProctoringRoom() {
|
||||||
super(new TypeKey<>(
|
super(new TypeKey<>(
|
||||||
CallType.UNDEFINED,
|
CallType.UNDEFINED,
|
||||||
EntityType.EXAM_PROCTOR_DATA,
|
EntityType.EXAM_PROCTOR_DATA,
|
||||||
new TypeReference<SEBProctoringConnectionData>() {
|
new TypeReference<SEBProctoringConnection>() {
|
||||||
}),
|
}),
|
||||||
HttpMethod.POST,
|
HttpMethod.POST,
|
||||||
MediaType.APPLICATION_FORM_URLENCODED,
|
MediaType.APPLICATION_FORM_URLENCODED,
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.ActivateTownhallRoom;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.ActivateTownhallRoom;
|
||||||
|
@ -82,7 +82,7 @@ public class ProctoringGUIService {
|
||||||
|
|
||||||
public static void setCurrentProctoringWindowData(
|
public static void setCurrentProctoringWindowData(
|
||||||
final String examId,
|
final String examId,
|
||||||
final SEBProctoringConnectionData data) {
|
final SEBProctoringConnection data) {
|
||||||
|
|
||||||
RWT.getUISession().getHttpSession().setAttribute(
|
RWT.getUISession().getHttpSession().setAttribute(
|
||||||
SESSION_ATTR_PROCTORING_DATA,
|
SESSION_ATTR_PROCTORING_DATA,
|
||||||
|
@ -103,7 +103,7 @@ public class ProctoringGUIService {
|
||||||
.orElseGet(() -> null);
|
.orElseGet(() -> null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<SEBProctoringConnectionData> registerNewSingleProcotringRoom(
|
public Result<SEBProctoringConnection> registerNewSingleProcotringRoom(
|
||||||
final String examId,
|
final String examId,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
final String subject,
|
final String subject,
|
||||||
|
@ -111,8 +111,8 @@ public class ProctoringGUIService {
|
||||||
|
|
||||||
return this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
|
return this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
||||||
.withFormParam(SEBProctoringConnectionData.ATTR_ROOM_NAME, roomName)
|
.withFormParam(SEBProctoringConnection.ATTR_ROOM_NAME, roomName)
|
||||||
.withFormParam(SEBProctoringConnectionData.ATTR_SUBJECT, subject)
|
.withFormParam(SEBProctoringConnection.ATTR_SUBJECT, subject)
|
||||||
.withFormParam(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionToken)
|
.withFormParam(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionToken)
|
||||||
.call()
|
.call()
|
||||||
.map(connection -> {
|
.map(connection -> {
|
||||||
|
@ -122,13 +122,13 @@ public class ProctoringGUIService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<SEBProctoringConnectionData> registerTownhallRoom(
|
public Result<SEBProctoringConnection> registerTownhallRoom(
|
||||||
final String examId,
|
final String examId,
|
||||||
final String subject) {
|
final String subject) {
|
||||||
|
|
||||||
return this.restService.getBuilder(ActivateTownhallRoom.class)
|
return this.restService.getBuilder(ActivateTownhallRoom.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
||||||
.withFormParam(SEBProctoringConnectionData.ATTR_SUBJECT, subject)
|
.withFormParam(SEBProctoringConnection.ATTR_SUBJECT, subject)
|
||||||
.call()
|
.call()
|
||||||
.map(connection -> {
|
.map(connection -> {
|
||||||
this.rooms.put(
|
this.rooms.put(
|
||||||
|
@ -139,7 +139,7 @@ public class ProctoringGUIService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result<SEBProctoringConnectionData> registerNewProcotringRoom(
|
public Result<SEBProctoringConnection> registerNewProcotringRoom(
|
||||||
final String examId,
|
final String examId,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
final String subject,
|
final String subject,
|
||||||
|
@ -147,8 +147,8 @@ public class ProctoringGUIService {
|
||||||
|
|
||||||
return this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
|
return this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
||||||
.withFormParam(SEBProctoringConnectionData.ATTR_ROOM_NAME, roomName)
|
.withFormParam(SEBProctoringConnection.ATTR_ROOM_NAME, roomName)
|
||||||
.withFormParam(SEBProctoringConnectionData.ATTR_SUBJECT, subject)
|
.withFormParam(SEBProctoringConnection.ATTR_SUBJECT, subject)
|
||||||
.withFormParam(
|
.withFormParam(
|
||||||
API.EXAM_API_SEB_CONNECTION_TOKEN,
|
API.EXAM_API_SEB_CONNECTION_TOKEN,
|
||||||
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR_CHAR))
|
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR_CHAR))
|
||||||
|
@ -172,7 +172,7 @@ public class ProctoringGUIService {
|
||||||
}
|
}
|
||||||
this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
|
this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
|
||||||
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
.withURIVariable(API.PARAM_MODEL_ID, examId)
|
||||||
.withFormParam(SEBProctoringConnectionData.ATTR_ROOM_NAME, room)
|
.withFormParam(SEBProctoringConnection.ATTR_ROOM_NAME, room)
|
||||||
.withFormParam(
|
.withFormParam(
|
||||||
API.EXAM_API_SEB_CONNECTION_TOKEN,
|
API.EXAM_API_SEB_CONNECTION_TOKEN,
|
||||||
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR_CHAR))
|
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR_CHAR))
|
||||||
|
@ -288,11 +288,11 @@ public class ProctoringGUIService {
|
||||||
|
|
||||||
public static class ProctoringWindowData {
|
public static class ProctoringWindowData {
|
||||||
public final String examId;
|
public final String examId;
|
||||||
public final SEBProctoringConnectionData connectionData;
|
public final SEBProctoringConnection connectionData;
|
||||||
|
|
||||||
protected ProctoringWindowData(
|
protected ProctoringWindowData(
|
||||||
final String examId,
|
final String examId,
|
||||||
final SEBProctoringConnectionData connectionData) {
|
final SEBProctoringConnection connectionData) {
|
||||||
this.examId = examId;
|
this.examId = examId;
|
||||||
this.connectionData = connectionData;
|
this.connectionData = connectionData;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
|
|
||||||
|
@ -33,36 +33,28 @@ public interface ExamProctoringService {
|
||||||
* @param roomName the name of the room
|
* @param roomName the name of the room
|
||||||
* @param subject name of the room
|
* @param subject name of the room
|
||||||
* @return SEBProctoringConnectionData that contains all connection data */
|
* @return SEBProctoringConnectionData that contains all connection data */
|
||||||
Result<SEBProctoringConnectionData> createProctorPublicRoomConnection(
|
Result<SEBProctoringConnection> createProctorPublicRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
final ProctoringSettings proctoringSettings,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
final String subject);
|
final String subject);
|
||||||
|
|
||||||
Result<SEBProctoringConnectionData> getClientExamCollectingRoomConnectionData(
|
Result<SEBProctoringConnection> getClientExamCollectingRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
|
||||||
final String connectionToken);
|
|
||||||
|
|
||||||
Result<SEBProctoringConnectionData> getClientExamCollectingRoomConnectionData(
|
|
||||||
final ProctoringSettings proctoringSettings,
|
final ProctoringSettings proctoringSettings,
|
||||||
final ClientConnection connection);
|
final ClientConnection connection);
|
||||||
|
|
||||||
Result<SEBProctoringConnectionData> getClientExamCollectingRoomConnectionData(
|
Result<SEBProctoringConnection> getClientExamCollectingRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
final ProctoringSettings proctoringSettings,
|
||||||
final String connectionToken,
|
final String connectionToken,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
final String subject);
|
final String subject);
|
||||||
|
|
||||||
Result<SEBProctoringConnectionData> getClientRoomConnectionData(
|
Result<SEBProctoringConnection> getClientRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
|
||||||
final String connectionToken);
|
|
||||||
|
|
||||||
Result<SEBProctoringConnectionData> getClientRoomConnectionData(
|
|
||||||
final ProctoringSettings examProctoring,
|
final ProctoringSettings examProctoring,
|
||||||
final String connectionToken,
|
final String connectionToken,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
final String subject);
|
final String subject);
|
||||||
|
|
||||||
Result<SEBProctoringConnectionData> createProctoringConnectionData(
|
Result<SEBProctoringConnection> createProctoringConnection(
|
||||||
final ProctoringServerType proctoringServerType,
|
final ProctoringServerType proctoringServerType,
|
||||||
final String connectionToken,
|
final String connectionToken,
|
||||||
final String url,
|
final String url,
|
||||||
|
|
|
@ -25,7 +25,7 @@ import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
@ -77,13 +77,13 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBProctoringConnectionData> createProctorPublicRoomConnection(
|
public Result<SEBProctoringConnection> createProctorPublicRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
final ProctoringSettings proctoringSettings,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
final String subject) {
|
final String subject) {
|
||||||
|
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
return createProctoringConnectionData(
|
return createProctoringConnection(
|
||||||
proctoringSettings.serverType,
|
proctoringSettings.serverType,
|
||||||
null,
|
null,
|
||||||
proctoringSettings.serverURL,
|
proctoringSettings.serverURL,
|
||||||
|
@ -100,19 +100,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBProctoringConnectionData> getClientExamCollectingRoomConnectionData(
|
public Result<SEBProctoringConnection> getClientExamCollectingRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
|
||||||
final String connectionToken) {
|
|
||||||
|
|
||||||
return this.examSessionService
|
|
||||||
.getConnectionData(connectionToken)
|
|
||||||
.flatMap(connection -> getClientExamCollectingRoomConnectionData(
|
|
||||||
proctoringSettings,
|
|
||||||
connection.clientConnection));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result<SEBProctoringConnectionData> getClientExamCollectingRoomConnectionData(
|
|
||||||
final ProctoringSettings proctoringSettings,
|
final ProctoringSettings proctoringSettings,
|
||||||
final ClientConnection connection) {
|
final ClientConnection connection) {
|
||||||
|
|
||||||
|
@ -122,7 +110,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
.getRoomName(connection.getRemoteProctoringRoomId())
|
.getRoomName(connection.getRemoteProctoringRoomId())
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
return createProctoringConnectionData(
|
return createProctoringConnection(
|
||||||
proctoringSettings.serverType,
|
proctoringSettings.serverType,
|
||||||
null,
|
null,
|
||||||
proctoringSettings.serverURL,
|
proctoringSettings.serverURL,
|
||||||
|
@ -139,7 +127,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBProctoringConnectionData> getClientExamCollectingRoomConnectionData(
|
public Result<SEBProctoringConnection> getClientExamCollectingRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
final ProctoringSettings proctoringSettings,
|
||||||
final String connectionToken,
|
final String connectionToken,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
|
@ -150,7 +138,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
.getConnectionData(connectionToken)
|
.getConnectionData(connectionToken)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
return createProctoringConnectionData(
|
return createProctoringConnection(
|
||||||
proctoringSettings.serverType,
|
proctoringSettings.serverType,
|
||||||
null,
|
null,
|
||||||
proctoringSettings.serverURL,
|
proctoringSettings.serverURL,
|
||||||
|
@ -167,29 +155,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBProctoringConnectionData> getClientRoomConnectionData(
|
public Result<SEBProctoringConnection> getClientRoomConnection(
|
||||||
final ProctoringSettings proctoringSettings,
|
|
||||||
final String connectionToken) {
|
|
||||||
|
|
||||||
return Result.tryCatch(() -> this.examSessionService
|
|
||||||
.getConnectionData(connectionToken)
|
|
||||||
.getOrThrow()
|
|
||||||
|
|
||||||
).flatMap(clientConnection -> {
|
|
||||||
final Encoder urlEncoder = Base64.getUrlEncoder().withoutPadding();
|
|
||||||
final String roomName = urlEncoder.encodeToString(
|
|
||||||
Utils.toByteArray(clientConnection.clientConnection.connectionToken));
|
|
||||||
|
|
||||||
return getClientRoomConnectionData(
|
|
||||||
proctoringSettings,
|
|
||||||
connectionToken,
|
|
||||||
roomName,
|
|
||||||
clientConnection.clientConnection.userSessionId);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result<SEBProctoringConnectionData> getClientRoomConnectionData(
|
|
||||||
final ProctoringSettings proctoringSettings,
|
final ProctoringSettings proctoringSettings,
|
||||||
final String connectionToken,
|
final String connectionToken,
|
||||||
final String roomName,
|
final String roomName,
|
||||||
|
@ -202,7 +168,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
.getConnectionData(connectionToken)
|
.getConnectionData(connectionToken)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
return createProctoringConnectionData(
|
return createProctoringConnection(
|
||||||
proctoringSettings.serverType,
|
proctoringSettings.serverType,
|
||||||
connectionToken,
|
connectionToken,
|
||||||
proctoringSettings.serverURL,
|
proctoringSettings.serverURL,
|
||||||
|
@ -220,7 +186,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBProctoringConnectionData> createProctoringConnectionData(
|
public Result<SEBProctoringConnection> createProctoringConnection(
|
||||||
final ProctoringServerType proctoringServerType,
|
final ProctoringServerType proctoringServerType,
|
||||||
final String connectionToken,
|
final String connectionToken,
|
||||||
final String url,
|
final String url,
|
||||||
|
@ -250,7 +216,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
|
||||||
host,
|
host,
|
||||||
moderator);
|
moderator);
|
||||||
|
|
||||||
return new SEBProctoringConnectionData(
|
return new SEBProctoringConnection(
|
||||||
proctoringServerType,
|
proctoringServerType,
|
||||||
connectionToken,
|
connectionToken,
|
||||||
host,
|
host,
|
||||||
|
|
|
@ -20,7 +20,7 @@ import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
|
||||||
|
@ -196,9 +196,9 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService
|
||||||
.getExamProctoring(examId)
|
.getExamProctoring(examId)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final SEBProctoringConnectionData proctoringData =
|
final SEBProctoringConnection proctoringData =
|
||||||
this.examAdminService.getExamProctoringService(proctoringSettings.serverType)
|
this.examAdminService.getExamProctoringService(proctoringSettings.serverType)
|
||||||
.flatMap(s -> s.getClientExamCollectingRoomConnectionData(
|
.flatMap(s -> s.getClientExamCollectingRoomConnection(
|
||||||
proctoringSettings,
|
proctoringSettings,
|
||||||
connectionToken,
|
connectionToken,
|
||||||
roomName,
|
roomName,
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Base64.Encoder;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -31,13 +33,14 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.RemoteProctoringRoom;
|
import ch.ethz.seb.sebserver.gbl.model.session.RemoteProctoringRoom;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
|
||||||
|
@ -108,14 +111,14 @@ public class ExamProctoringController {
|
||||||
method = RequestMethod.GET,
|
method = RequestMethod.GET,
|
||||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
public SEBProctoringConnectionData getProctorRoomData(
|
public SEBProctoringConnection getProctorRoomData(
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = API.PARAM_INSTITUTION_ID,
|
name = API.PARAM_INSTITUTION_ID,
|
||||||
required = true,
|
required = true,
|
||||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||||
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
|
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
|
||||||
@RequestParam(name = SEBProctoringConnectionData.ATTR_ROOM_NAME, required = true) final String roomName,
|
@RequestParam(name = SEBProctoringConnection.ATTR_ROOM_NAME, required = true) final String roomName,
|
||||||
@RequestParam(name = SEBProctoringConnectionData.ATTR_SUBJECT, required = false) final String subject) {
|
@RequestParam(name = SEBProctoringConnection.ATTR_SUBJECT, required = false) final String subject) {
|
||||||
|
|
||||||
checkAccess(institutionId, examId);
|
checkAccess(institutionId, examId);
|
||||||
|
|
||||||
|
@ -217,27 +220,12 @@ public class ExamProctoringController {
|
||||||
|
|
||||||
checkAccess(institutionId, examId);
|
checkAccess(institutionId, examId);
|
||||||
|
|
||||||
final ProctoringSettings settings = this.examSessionService
|
final ProctoringSettings proctoringSettings = this.examSessionService
|
||||||
.getRunningExam(examId)
|
.getRunningExam(examId)
|
||||||
.flatMap(this.examAdminService::getExamProctoring)
|
.flatMap(this.examAdminService::getExamProctoring)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
final ExamProctoringService examProctoringService = this.examAdminService
|
sendJoinInstructions(connectionTokens, proctoringSettings);
|
||||||
.getExamProctoringService(settings.serverType)
|
|
||||||
.getOrThrow();
|
|
||||||
|
|
||||||
Arrays.asList(StringUtils.split(connectionTokens, Constants.LIST_SEPARATOR))
|
|
||||||
.stream()
|
|
||||||
.forEach(connectionToken -> {
|
|
||||||
examProctoringService
|
|
||||||
.getClientExamCollectingRoomConnectionData(
|
|
||||||
settings,
|
|
||||||
connectionToken)
|
|
||||||
.flatMap(data -> this.sendJoinInstruction(examId, connectionToken, data))
|
|
||||||
.onError(error -> log.error("Failed to send rejoin for: {} cause: {}",
|
|
||||||
connectionToken,
|
|
||||||
error.getMessage()));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
|
@ -245,17 +233,17 @@ public class ExamProctoringController {
|
||||||
+ API.EXAM_PROCTORING_JOIN_ROOM_PATH_SEGMENT,
|
+ API.EXAM_PROCTORING_JOIN_ROOM_PATH_SEGMENT,
|
||||||
method = RequestMethod.POST,
|
method = RequestMethod.POST,
|
||||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
public SEBProctoringConnectionData sendJoinProctoringRoomToClients(
|
public SEBProctoringConnection sendJoinProctoringRoomToClients(
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = API.PARAM_INSTITUTION_ID,
|
name = API.PARAM_INSTITUTION_ID,
|
||||||
required = true,
|
required = true,
|
||||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||||
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
|
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = SEBProctoringConnectionData.ATTR_ROOM_NAME,
|
name = SEBProctoringConnection.ATTR_ROOM_NAME,
|
||||||
required = true) final String roomName,
|
required = true) final String roomName,
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = SEBProctoringConnectionData.ATTR_SUBJECT,
|
name = SEBProctoringConnection.ATTR_SUBJECT,
|
||||||
required = false) final String subject,
|
required = false) final String subject,
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = API.EXAM_API_SEB_CONNECTION_TOKEN,
|
name = API.EXAM_API_SEB_CONNECTION_TOKEN,
|
||||||
|
@ -273,33 +261,24 @@ public class ExamProctoringController {
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(connectionTokens)) {
|
if (StringUtils.isNotBlank(connectionTokens)) {
|
||||||
final boolean single = connectionTokens.contains(Constants.LIST_SEPARATOR);
|
|
||||||
(single
|
Arrays.asList(connectionTokens.split(Constants.LIST_SEPARATOR))
|
||||||
? Arrays.asList(StringUtils.split(connectionTokens, Constants.LIST_SEPARATOR))
|
|
||||||
: Arrays.asList(connectionTokens))
|
|
||||||
.stream()
|
.stream()
|
||||||
.forEach(connectionToken -> {
|
.forEach(connectionToken -> {
|
||||||
final SEBProctoringConnectionData data = (single)
|
final SEBProctoringConnection proctoringConnection =
|
||||||
? examProctoringService
|
examProctoringService
|
||||||
.getClientRoomConnectionData(settings, connectionToken)
|
.getClientRoomConnection(
|
||||||
.onError(error -> log.error(
|
|
||||||
"Failed to get client room connection data for {} cause: {}",
|
|
||||||
connectionToken,
|
|
||||||
error.getMessage()))
|
|
||||||
.get()
|
|
||||||
: examProctoringService
|
|
||||||
.getClientRoomConnectionData(
|
|
||||||
settings,
|
settings,
|
||||||
connectionToken,
|
connectionToken,
|
||||||
roomName,
|
verifyRoomName(roomName, connectionToken),
|
||||||
(StringUtils.isNotBlank(subject)) ? subject : roomName)
|
(StringUtils.isNotBlank(subject)) ? subject : roomName)
|
||||||
.onError(error -> log.error(
|
.onError(error -> log.error(
|
||||||
"Failed to get client room connection data for {} cause: {}",
|
"Failed to get client room connection data for {} cause: {}",
|
||||||
connectionToken,
|
connectionToken,
|
||||||
error.getMessage()))
|
error.getMessage()))
|
||||||
.get();
|
.get();
|
||||||
if (data != null) {
|
if (proctoringConnection != null) {
|
||||||
sendJoinInstruction(examId, connectionToken, data)
|
sendJoinInstruction(settings.examId, connectionToken, proctoringConnection)
|
||||||
.onError(error -> log.error(
|
.onError(error -> log.error(
|
||||||
"Failed to send proctoring leave instruction to client: {} cause: {}",
|
"Failed to send proctoring leave instruction to client: {} cause: {}",
|
||||||
connectionToken,
|
connectionToken,
|
||||||
|
@ -315,6 +294,16 @@ public class ExamProctoringController {
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String verifyRoomName(final String requestedRoomName, final String connectionToken) {
|
||||||
|
if (StringUtils.isNotBlank(requestedRoomName)) {
|
||||||
|
return requestedRoomName;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Encoder urlEncoder = Base64.getUrlEncoder().withoutPadding();
|
||||||
|
return urlEncoder.encodeToString(
|
||||||
|
Utils.toByteArray(connectionToken));
|
||||||
|
}
|
||||||
|
|
||||||
@RequestMapping(
|
@RequestMapping(
|
||||||
path = API.MODEL_ID_VAR_PATH_SEGMENT
|
path = API.MODEL_ID_VAR_PATH_SEGMENT
|
||||||
+ API.EXAM_PROCTORING_TOWNHALL_ROOM_DATA,
|
+ API.EXAM_PROCTORING_TOWNHALL_ROOM_DATA,
|
||||||
|
@ -338,14 +327,14 @@ public class ExamProctoringController {
|
||||||
+ API.EXAM_PROCTORING_ACTIVATE_TOWNHALL_ROOM,
|
+ API.EXAM_PROCTORING_ACTIVATE_TOWNHALL_ROOM,
|
||||||
method = RequestMethod.POST,
|
method = RequestMethod.POST,
|
||||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
public SEBProctoringConnectionData activateTownhall(
|
public SEBProctoringConnection activateTownhall(
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = API.PARAM_INSTITUTION_ID,
|
name = API.PARAM_INSTITUTION_ID,
|
||||||
required = true,
|
required = true,
|
||||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||||
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
|
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
|
||||||
@RequestParam(
|
@RequestParam(
|
||||||
name = SEBProctoringConnectionData.ATTR_SUBJECT,
|
name = SEBProctoringConnection.ATTR_SUBJECT,
|
||||||
required = false) final String subject) {
|
required = false) final String subject) {
|
||||||
|
|
||||||
checkAccess(institutionId, examId);
|
checkAccess(institutionId, examId);
|
||||||
|
@ -371,8 +360,8 @@ public class ExamProctoringController {
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
.forEach(cc -> {
|
.forEach(cc -> {
|
||||||
final SEBProctoringConnectionData data = examProctoringService
|
final SEBProctoringConnection data = examProctoringService
|
||||||
.getClientRoomConnectionData(
|
.getClientRoomConnection(
|
||||||
settings,
|
settings,
|
||||||
cc.clientConnection.connectionToken,
|
cc.clientConnection.connectionToken,
|
||||||
townhallRoom.name,
|
townhallRoom.name,
|
||||||
|
@ -431,7 +420,7 @@ public class ExamProctoringController {
|
||||||
.stream()
|
.stream()
|
||||||
.forEach(cc -> {
|
.forEach(cc -> {
|
||||||
examProctoringService
|
examProctoringService
|
||||||
.getClientExamCollectingRoomConnectionData(
|
.getClientExamCollectingRoomConnection(
|
||||||
settings,
|
settings,
|
||||||
cc.clientConnection)
|
cc.clientConnection)
|
||||||
.flatMap(data -> this.sendJoinInstruction(
|
.flatMap(data -> this.sendJoinInstruction(
|
||||||
|
@ -455,9 +444,25 @@ public class ExamProctoringController {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(connectionTokens)) {
|
final boolean definedClients = StringUtils.isNotBlank(connectionTokens);
|
||||||
// we have defined connection tokens to send instructions to
|
final boolean inTownhall = this.examProcotringRoomService.getTownhallRoomData(examId).hasValue();
|
||||||
|
final boolean roomSpecified = StringUtils.isNotBlank(roomName);
|
||||||
|
|
||||||
|
if (definedClients) {
|
||||||
|
sendBroadcastInstructionsToClients(examId, connectionTokens, attributes);
|
||||||
|
} else if (inTownhall) {
|
||||||
|
sendBroadcastInstructionToClientsInExam(examId, attributes);
|
||||||
|
} else if (roomSpecified) {
|
||||||
|
sendBroadcastInstructionToClientsInRoom(examId, roomName, attributes);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("API attribute validation error: missing "
|
||||||
|
+ Domain.REMOTE_PROCTORING_ROOM.ATTR_ID + " and/or" +
|
||||||
|
API.EXAM_API_SEB_CONNECTION_TOKEN + " attribute");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendBroadcastInstructionsToClients(final Long examId, final String connectionTokens,
|
||||||
|
final Map<String, String> attributes) {
|
||||||
final boolean single = connectionTokens.contains(Constants.LIST_SEPARATOR);
|
final boolean single = connectionTokens.contains(Constants.LIST_SEPARATOR);
|
||||||
(single
|
(single
|
||||||
? Arrays.asList(StringUtils.split(connectionTokens, Constants.LIST_SEPARATOR))
|
? Arrays.asList(StringUtils.split(connectionTokens, Constants.LIST_SEPARATOR))
|
||||||
|
@ -476,10 +481,11 @@ public class ExamProctoringController {
|
||||||
error));
|
error));
|
||||||
|
|
||||||
});
|
});
|
||||||
} else if (this.examProcotringRoomService.getTownhallRoomData(examId).hasValue()) {
|
}
|
||||||
// we are in the town hall so all active connections are involved
|
|
||||||
|
|
||||||
this.examSessionService.getAllActiveConnectionData(examId)
|
private void sendBroadcastInstructionToClientsInExam(final Long examId, final Map<String, String> attributes) {
|
||||||
|
this.examSessionService
|
||||||
|
.getAllActiveConnectionData(examId)
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
.forEach(connection -> {
|
.forEach(connection -> {
|
||||||
|
@ -494,10 +500,15 @@ public class ExamProctoringController {
|
||||||
connection.clientConnection.connectionToken,
|
connection.clientConnection.connectionToken,
|
||||||
error));
|
error));
|
||||||
});
|
});
|
||||||
} else if (StringUtils.isNotBlank(roomName)) {
|
}
|
||||||
// we have a room name so all connection of this room are involved
|
|
||||||
|
|
||||||
this.examProcotringRoomService.getRoomConnections(examId, roomName)
|
private void sendBroadcastInstructionToClientsInRoom(
|
||||||
|
final Long examId,
|
||||||
|
final String roomName,
|
||||||
|
final Map<String, String> attributes) {
|
||||||
|
|
||||||
|
this.examProcotringRoomService
|
||||||
|
.getRoomConnections(examId, roomName)
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(ExamSessionService.ACTIVE_CONNECTION_FILTER)
|
.filter(ExamSessionService.ACTIVE_CONNECTION_FILTER)
|
||||||
|
@ -513,19 +524,48 @@ public class ExamProctoringController {
|
||||||
connection.connectionToken,
|
connection.connectionToken,
|
||||||
error));
|
error));
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
throw new RuntimeException("API attribute validation error: missing "
|
|
||||||
+ Domain.REMOTE_PROCTORING_ROOM.ATTR_ID + " and/or" +
|
|
||||||
API.EXAM_API_SEB_CONNECTION_TOKEN + " attribute");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendJoinInstructions(
|
||||||
|
final String connectionTokens,
|
||||||
|
final ProctoringSettings proctoringSettings) {
|
||||||
|
|
||||||
|
final ExamProctoringService examProctoringService = this.examAdminService
|
||||||
|
.getExamProctoringService(proctoringSettings.serverType)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
|
Arrays.asList(StringUtils.split(connectionTokens, Constants.LIST_SEPARATOR))
|
||||||
|
.stream()
|
||||||
|
.forEach(connectionToken -> {
|
||||||
|
sendJoinInstructionToClient(proctoringSettings, examProctoringService, connectionToken);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendJoinInstructionToClient(
|
||||||
|
final ProctoringSettings proctoringSettings,
|
||||||
|
final ExamProctoringService examProctoringService,
|
||||||
|
final String connectionToken) {
|
||||||
|
|
||||||
|
this.examSessionService
|
||||||
|
.getConnectionData(connectionToken)
|
||||||
|
.flatMap(connection -> examProctoringService.getClientExamCollectingRoomConnection(
|
||||||
|
proctoringSettings,
|
||||||
|
connection.clientConnection))
|
||||||
|
.flatMap(data -> this.sendJoinInstruction(
|
||||||
|
proctoringSettings.examId,
|
||||||
|
connectionToken, data))
|
||||||
|
.onError(error -> log.error("Failed to send rejoin for: {} cause: {}",
|
||||||
|
connectionToken,
|
||||||
|
error.getMessage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<Void> sendJoinInstruction(
|
private Result<Void> sendJoinInstruction(
|
||||||
final Long examId,
|
final Long examId,
|
||||||
final String connectionToken,
|
final String connectionToken,
|
||||||
final SEBProctoringConnectionData data) {
|
final SEBProctoringConnection data) {
|
||||||
|
|
||||||
final Map<String, String> attributes = new HashMap<>();
|
final Map<String, String> attributes = new HashMap<>();
|
||||||
|
|
||||||
attributes.put(
|
attributes.put(
|
||||||
ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_PROCTORING.SERVICE_TYPE,
|
ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_PROCTORING.SERVICE_TYPE,
|
||||||
ProctoringSettings.ProctoringServerType.JITSI_MEET.name());
|
ProctoringSettings.ProctoringServerType.JITSI_MEET.name());
|
||||||
|
@ -541,6 +581,7 @@ public class ExamProctoringController {
|
||||||
attributes.put(
|
attributes.put(
|
||||||
ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_PROCTORING.JITSI_TOKEN,
|
ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_PROCTORING.JITSI_TOKEN,
|
||||||
data.accessToken);
|
data.accessToken);
|
||||||
|
|
||||||
return this.sebInstructionService.registerInstruction(
|
return this.sebInstructionService.registerInstruction(
|
||||||
examId,
|
examId,
|
||||||
InstructionType.SEB_PROCTORING,
|
InstructionType.SEB_PROCTORING,
|
||||||
|
|
|
@ -18,7 +18,7 @@ import org.junit.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnectionData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||||
|
|
||||||
public class ExamJITSIProctoringServiceTest {
|
public class ExamJITSIProctoringServiceTest {
|
||||||
|
@ -63,7 +63,7 @@ public class ExamJITSIProctoringServiceTest {
|
||||||
Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123");
|
Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123");
|
||||||
final ExamJITSIProctoringService examJITSIProctoringService =
|
final ExamJITSIProctoringService examJITSIProctoringService =
|
||||||
new ExamJITSIProctoringService(null, null, null, cryptorMock);
|
new ExamJITSIProctoringService(null, null, null, cryptorMock);
|
||||||
final SEBProctoringConnectionData data = examJITSIProctoringService.createProctoringConnectionData(
|
final SEBProctoringConnection data = examJITSIProctoringService.createProctoringConnection(
|
||||||
ProctoringServerType.JITSI_MEET,
|
ProctoringServerType.JITSI_MEET,
|
||||||
"connectionToken",
|
"connectionToken",
|
||||||
"https://seb-jitsi.example.ch",
|
"https://seb-jitsi.example.ch",
|
||||||
|
|
Loading…
Reference in a new issue