proctoring refactoring and tests

This commit is contained in:
anhefti 2021-02-17 16:52:28 +01:00
parent 1796ff4a7a
commit 2f2a318f9d
26 changed files with 311 additions and 240 deletions

View file

@ -12,10 +12,10 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
@JsonIgnoreProperties(ignoreUnknown = true)
public class SEBProctoringConnection {
public class ProctoringRoomConnection {
public static final String ATTR_CONNECTION_TOKEN = "connectionToken";
public static final String ATTR_SERVER_HOST = "serverHost";
@ -25,7 +25,7 @@ public class SEBProctoringConnection {
public static final String ATTR_ACCESS_TOKEN = "accessToken";
public static final String ATTR_CONNECTION_URL = "connectionURL";
@JsonProperty(ProctoringSettings.ATTR_SERVER_TYPE)
@JsonProperty(ProctoringServiceSettings.ATTR_SERVER_TYPE)
public final ProctoringServerType proctoringServerType;
@JsonProperty(ATTR_CONNECTION_TOKEN)
@ -47,8 +47,8 @@ public class SEBProctoringConnection {
public final String accessToken;
@JsonCreator
public SEBProctoringConnection(
@JsonProperty(ProctoringSettings.ATTR_SERVER_TYPE) final ProctoringServerType proctoringServerType,
public ProctoringRoomConnection(
@JsonProperty(ProctoringServiceSettings.ATTR_SERVER_TYPE) final ProctoringServerType proctoringServerType,
@JsonProperty(ATTR_CONNECTION_TOKEN) final String connectionToken,
@JsonProperty(ATTR_SERVER_HOST) final String serverHost,
@JsonProperty(ATTR_SERVER_URL) final String serverURL,

View file

@ -22,7 +22,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.ValidProctoringS
@JsonIgnoreProperties(ignoreUnknown = true)
@ValidProctoringSettings
public class ProctoringSettings implements Entity {
public class ProctoringServiceSettings implements Entity {
public enum ProctoringServerType {
JITSI_MEET
@ -59,7 +59,7 @@ public class ProctoringSettings implements Entity {
public final Integer collectingRoomSize;
@JsonCreator
public ProctoringSettings(
public ProctoringServiceSettings(
@JsonProperty(Domain.EXAM.ATTR_ID) final Long examId,
@JsonProperty(ATTR_ENABLE_PROCTORING) final Boolean enableProctoring,
@JsonProperty(ATTR_SERVER_TYPE) final ProctoringServerType serverType,
@ -137,7 +137,7 @@ public class ProctoringSettings implements Entity {
return false;
if (getClass() != obj.getClass())
return false;
final ProctoringSettings other = (ProctoringSettings) obj;
final ProctoringServiceSettings other = (ProctoringServiceSettings) obj;
if (this.examId == null) {
if (other.examId != null)
return false;

View file

@ -33,7 +33,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
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.ExamStatus;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.Features;
@ -350,7 +350,7 @@ public class ExamForm implements TemplateComposer {
.getBuilder(GetProctoringSettings.class)
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
.call()
.map(ProctoringSettings::getEnableProctoring)
.map(ProctoringServiceSettings::getEnableProctoring)
.getOr(false);
final PageActionBuilder actionBuilder = this.pageService.pageActionBuilder(formContext

View file

@ -22,8 +22,8 @@ import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
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.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
@ -121,24 +121,24 @@ public class ExamProctoringSettings {
}
final EntityKey entityKey = pageContext.getEntityKey();
ProctoringSettings examProctoring = null;
ProctoringServiceSettings examProctoring = null;
try {
final Form form = formHandle.getForm();
form.clearErrors();
final boolean enabled = BooleanUtils.toBoolean(
form.getFieldValue(ProctoringSettings.ATTR_ENABLE_PROCTORING));
form.getFieldValue(ProctoringServiceSettings.ATTR_ENABLE_PROCTORING));
final ProctoringServerType serverType = ProctoringServerType.valueOf(
form.getFieldValue(ProctoringSettings.ATTR_SERVER_TYPE));
form.getFieldValue(ProctoringServiceSettings.ATTR_SERVER_TYPE));
examProctoring = new ProctoringSettings(
examProctoring = new ProctoringServiceSettings(
Long.parseLong(entityKey.modelId),
enabled,
serverType,
form.getFieldValue(ProctoringSettings.ATTR_SERVER_URL),
Integer.parseInt(form.getFieldValue(ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE)),
form.getFieldValue(ProctoringSettings.ATTR_APP_KEY),
form.getFieldValue(ProctoringSettings.ATTR_APP_SECRET));
form.getFieldValue(ProctoringServiceSettings.ATTR_SERVER_URL),
Integer.parseInt(form.getFieldValue(ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE)),
form.getFieldValue(ProctoringServiceSettings.ATTR_APP_KEY),
form.getFieldValue(ProctoringServiceSettings.ATTR_APP_SECRET));
} catch (final Exception e) {
log.error("Unexpected error while trying to get settings from form: ", e);
@ -198,7 +198,7 @@ public class ExamProctoringSettings {
.getWidgetFactory()
.createPopupScrollComposite(parent);
final ProctoringSettings proctoringSettings = restService
final ProctoringServiceSettings proctoringSettings = restService
.getBuilder(GetProctoringSettings.class)
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
.call()
@ -208,7 +208,7 @@ public class ExamProctoringSettings {
.copyOf(content)
.clearEntityKeys();
final FormHandle<ProctoringSettings> formHandle = this.pageService.formBuilder(
final FormHandle<ProctoringServiceSettings> formHandle = this.pageService.formBuilder(
formContext)
.withDefaultSpanInput(5)
.withEmptyCellSeparation(true)
@ -224,24 +224,24 @@ public class ExamProctoringSettings {
.readonly(true))
.addField(FormBuilder.checkbox(
ProctoringSettings.ATTR_ENABLE_PROCTORING,
ProctoringServiceSettings.ATTR_ENABLE_PROCTORING,
SEB_PROCTORING_FORM_ENABLE,
String.valueOf(proctoringSettings.enableProctoring)))
.addField(FormBuilder.singleSelection(
ProctoringSettings.ATTR_SERVER_TYPE,
ProctoringServiceSettings.ATTR_SERVER_TYPE,
SEB_PROCTORING_FORM_TYPE,
proctoringSettings.serverType.name(),
resourceService::examProctoringTypeResources))
.addField(FormBuilder.text(
ProctoringSettings.ATTR_SERVER_URL,
ProctoringServiceSettings.ATTR_SERVER_URL,
SEB_PROCTORING_FORM_URL,
proctoringSettings.serverURL))
.withDefaultSpanInput(1)
.addField(FormBuilder.text(
ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE,
ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE,
SEB_PROCTORING_FORM_ROOM_SIZE,
String.valueOf(proctoringSettings.getCollectingRoomSize()))
.asNumber(numString -> Long.parseLong(numString)))
@ -249,13 +249,13 @@ public class ExamProctoringSettings {
.withDefaultSpanEmptyCell(4)
.addField(FormBuilder.text(
ProctoringSettings.ATTR_APP_KEY,
ProctoringServiceSettings.ATTR_APP_KEY,
SEB_PROCTORING_FORM_APPKEY,
proctoringSettings.appKey))
.withEmptyCellSeparation(false)
.addField(FormBuilder.password(
ProctoringSettings.ATTR_APP_SECRET,
ProctoringServiceSettings.ATTR_APP_SECRET,
SEB_PROCTORING_FORM_SECRET,
(proctoringSettings.appSecret != null)
? String.valueOf(proctoringSettings.appSecret)

View file

@ -31,8 +31,8 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
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.Indicator;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
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.ClientEvent;
@ -64,7 +64,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.ConfirmPe
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetClientConnectionData;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetPendingClientNotifications;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProcotringRooms;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProctorRoomConnectionData;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProctorRoomConnection;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.service.session.ClientConnectionDetails;
import ch.ethz.seb.sebserver.gui.service.session.InstructionProcessor;
@ -374,7 +374,7 @@ public class MonitoringClientConnection implements TemplateComposer {
connectionData.clientConnection.status == ConnectionStatus.ACTIVE);
if (connectionData.clientConnection.status == ConnectionStatus.ACTIVE) {
final ProctoringSettings procotringSettings = restService
final ProctoringServiceSettings procotringSettings = restService
.getBuilder(GetProctoringSettings.class)
.withURIVariable(API.PARAM_MODEL_ID, parentEntityKey.modelId)
.call()
@ -438,7 +438,7 @@ public class MonitoringClientConnection implements TemplateComposer {
final String examId = action.getEntityKey().modelId;
final ProctoringSettings proctoringSettings = this.pageService.getRestService()
final ProctoringServiceSettings proctoringSettings = this.pageService.getRestService()
.getBuilder(GetProctoringSettings.class)
.withURIVariable(API.PARAM_MODEL_ID, examId)
.call()
@ -455,12 +455,12 @@ public class MonitoringClientConnection implements TemplateComposer {
if (roomOptional.isPresent()) {
final RemoteProctoringRoom room = roomOptional.get();
final SEBProctoringConnection proctoringConnectionData = this.pageService
final ProctoringRoomConnection proctoringConnectionData = this.pageService
.getRestService()
.getBuilder(GetProctorRoomConnectionData.class)
.getBuilder(GetProctorRoomConnection.class)
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(proctoringSettings.examId))
.withQueryParam(SEBProctoringConnection.ATTR_ROOM_NAME, room.name)
.withQueryParam(SEBProctoringConnection.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
.withQueryParam(ProctoringRoomConnection.ATTR_ROOM_NAME, room.name)
.withQueryParam(ProctoringRoomConnection.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
.call()
.getOrThrow();
@ -499,7 +499,7 @@ public class MonitoringClientConnection implements TemplateComposer {
.getProctoringGUIService();
if (!proctoringGUIService.hasRoom(roomName)) {
final SEBProctoringConnection proctoringConnectionData = proctoringGUIService
final ProctoringRoomConnection proctoringConnectionData = proctoringGUIService
.registerNewSingleProcotringRoom(
examId,
roomName,

View file

@ -43,8 +43,8 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
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.Indicator;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
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.ClientConnectionData;
@ -76,7 +76,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetIndicator
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetProctoringSettings;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetClientConnectionDataList;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProcotringRooms;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProctorRoomConnectionData;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetProctorRoomConnection;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.session.GetTownhallRoom;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.service.session.ClientConnectionTable;
@ -349,7 +349,7 @@ public class MonitoringRunningExam implements TemplateComposer {
}
final ProctoringSettings proctoringSettings = restService
final ProctoringServiceSettings proctoringSettings = restService
.getBuilder(GetProctoringSettings.class)
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
.call()
@ -445,7 +445,7 @@ public class MonitoringRunningExam implements TemplateComposer {
String activeAllRoomName = proctoringGUIService.getTownhallRoom(examId.modelId);
if (activeAllRoomName == null) {
final SEBProctoringConnection proctoringConnectionData = proctoringGUIService
final ProctoringRoomConnection proctoringConnectionData = proctoringGUIService
.registerTownhallRoom(
examId.modelId,
this.pageService.getI18nSupport().getText(EXAM_ROOM_NAME))
@ -528,7 +528,7 @@ public class MonitoringRunningExam implements TemplateComposer {
final PageContext pageContext,
final Map<String, Pair<RemoteProctoringRoom, TreeItem>> rooms,
final PageActionBuilder actionBuilder,
final ProctoringSettings proctoringSettings) {
final ProctoringServiceSettings proctoringSettings) {
updateTownhallButton(entityKey, pageContext);
final I18nSupport i18nSupport = this.pageService.getI18nSupport();
@ -638,16 +638,16 @@ public class MonitoringRunningExam implements TemplateComposer {
}
private PageAction showExamProctoringRoom(
final ProctoringSettings proctoringSettings,
final ProctoringServiceSettings proctoringSettings,
final RemoteProctoringRoom room,
final PageAction action) {
final SEBProctoringConnection proctoringConnectionData = this.pageService
final ProctoringRoomConnection proctoringConnectionData = this.pageService
.getRestService()
.getBuilder(GetProctorRoomConnectionData.class)
.getBuilder(GetProctorRoomConnection.class)
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(proctoringSettings.examId))
.withQueryParam(SEBProctoringConnection.ATTR_ROOM_NAME, room.name)
.withQueryParam(SEBProctoringConnection.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
.withQueryParam(ProctoringRoomConnection.ATTR_ROOM_NAME, room.name)
.withQueryParam(ProctoringRoomConnection.ATTR_SUBJECT, Utils.encodeFormURL_UTF_8(room.subject))
.call()
.getOrThrow();

View file

@ -40,7 +40,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.ExamConfigurationMap;
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSEBRestriction.PermissionComponent;
import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSEBRestriction.WhiteListPath;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode;

View file

@ -8,7 +8,7 @@
package ch.ethz.seb.sebserver.gui.service.page;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
public interface RemoteProctoringView extends TemplateComposer {

View file

@ -25,7 +25,7 @@ import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.GuiServiceInfo;

View file

@ -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.EntityType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
@Lazy
@Component
@GuiProfile
public class GetProctoringSettings extends RestCall<ProctoringSettings> {
public class GetProctoringSettings extends RestCall<ProctoringServiceSettings> {
public GetProctoringSettings() {
super(new TypeKey<>(
CallType.GET_SINGLE,
EntityType.EXAM_PROCTOR_DATA,
new TypeReference<ProctoringSettings>() {
new TypeReference<ProctoringServiceSettings>() {
}),
HttpMethod.GET,
MediaType.APPLICATION_JSON,

View file

@ -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.EntityType;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
@Lazy
@Component
@GuiProfile
public class ActivateTownhallRoom extends RestCall<SEBProctoringConnection> {
public class ActivateTownhallRoom extends RestCall<ProctoringRoomConnection> {
public ActivateTownhallRoom() {
super(new TypeKey<>(
CallType.UNDEFINED,
EntityType.EXAM_PROCTOR_DATA,
new TypeReference<SEBProctoringConnection>() {
new TypeReference<ProctoringRoomConnection>() {
}),
HttpMethod.POST,
MediaType.APPLICATION_FORM_URLENCODED,

View file

@ -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.EntityType;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
@Lazy
@Component
@GuiProfile
public class GetProctorRoomConnectionData extends RestCall<SEBProctoringConnection> {
public class GetProctorRoomConnection extends RestCall<ProctoringRoomConnection> {
public GetProctorRoomConnectionData() {
public GetProctorRoomConnection() {
super(new TypeKey<>(
CallType.GET_SINGLE,
EntityType.EXAM_PROCTOR_DATA,
new TypeReference<SEBProctoringConnection>() {
new TypeReference<ProctoringRoomConnection>() {
}),
HttpMethod.GET,
MediaType.APPLICATION_FORM_URLENCODED,

View file

@ -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.EntityType;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
@Lazy
@Component
@GuiProfile
public class SendJoinRemoteProctoringRoom extends RestCall<SEBProctoringConnection> {
public class SendJoinRemoteProctoringRoom extends RestCall<ProctoringRoomConnection> {
public SendJoinRemoteProctoringRoom() {
super(new TypeKey<>(
CallType.UNDEFINED,
EntityType.EXAM_PROCTOR_DATA,
new TypeReference<SEBProctoringConnection>() {
new TypeReference<ProctoringRoomConnection>() {
}),
HttpMethod.POST,
MediaType.APPLICATION_FORM_URLENCODED,

View file

@ -27,7 +27,7 @@ import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
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.session.ActivateTownhallRoom;
@ -82,7 +82,7 @@ public class ProctoringGUIService {
public static void setCurrentProctoringWindowData(
final String examId,
final SEBProctoringConnection data) {
final ProctoringRoomConnection data) {
RWT.getUISession().getHttpSession().setAttribute(
SESSION_ATTR_PROCTORING_DATA,
@ -103,7 +103,7 @@ public class ProctoringGUIService {
.orElseGet(() -> null);
}
public Result<SEBProctoringConnection> registerNewSingleProcotringRoom(
public Result<ProctoringRoomConnection> registerNewSingleProcotringRoom(
final String examId,
final String roomName,
final String subject,
@ -111,8 +111,8 @@ public class ProctoringGUIService {
return this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
.withURIVariable(API.PARAM_MODEL_ID, examId)
.withFormParam(SEBProctoringConnection.ATTR_ROOM_NAME, roomName)
.withFormParam(SEBProctoringConnection.ATTR_SUBJECT, subject)
.withFormParam(ProctoringRoomConnection.ATTR_ROOM_NAME, roomName)
.withFormParam(ProctoringRoomConnection.ATTR_SUBJECT, subject)
.withFormParam(API.EXAM_API_SEB_CONNECTION_TOKEN, connectionToken)
.call()
.map(connection -> {
@ -122,13 +122,13 @@ public class ProctoringGUIService {
});
}
public Result<SEBProctoringConnection> registerTownhallRoom(
public Result<ProctoringRoomConnection> registerTownhallRoom(
final String examId,
final String subject) {
return this.restService.getBuilder(ActivateTownhallRoom.class)
.withURIVariable(API.PARAM_MODEL_ID, examId)
.withFormParam(SEBProctoringConnection.ATTR_SUBJECT, subject)
.withFormParam(ProctoringRoomConnection.ATTR_SUBJECT, subject)
.call()
.map(connection -> {
this.rooms.put(
@ -139,7 +139,7 @@ public class ProctoringGUIService {
});
}
public Result<SEBProctoringConnection> registerNewProcotringRoom(
public Result<ProctoringRoomConnection> registerNewProcotringRoom(
final String examId,
final String roomName,
final String subject,
@ -147,8 +147,8 @@ public class ProctoringGUIService {
return this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
.withURIVariable(API.PARAM_MODEL_ID, examId)
.withFormParam(SEBProctoringConnection.ATTR_ROOM_NAME, roomName)
.withFormParam(SEBProctoringConnection.ATTR_SUBJECT, subject)
.withFormParam(ProctoringRoomConnection.ATTR_ROOM_NAME, roomName)
.withFormParam(ProctoringRoomConnection.ATTR_SUBJECT, subject)
.withFormParam(
API.EXAM_API_SEB_CONNECTION_TOKEN,
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR_CHAR))
@ -172,7 +172,7 @@ public class ProctoringGUIService {
}
this.restService.getBuilder(SendJoinRemoteProctoringRoom.class)
.withURIVariable(API.PARAM_MODEL_ID, examId)
.withFormParam(SEBProctoringConnection.ATTR_ROOM_NAME, room)
.withFormParam(ProctoringRoomConnection.ATTR_ROOM_NAME, room)
.withFormParam(
API.EXAM_API_SEB_CONNECTION_TOKEN,
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR_CHAR))
@ -288,11 +288,11 @@ public class ProctoringGUIService {
public static class ProctoringWindowData {
public final String examId;
public final SEBProctoringConnection connectionData;
public final ProctoringRoomConnection connectionData;
protected ProctoringWindowData(
final String examId,
final SEBProctoringConnection connectionData) {
final ProctoringRoomConnection connectionData) {
this.examId = examId;
this.connectionData = connectionData;
}

View file

@ -9,8 +9,8 @@
package ch.ethz.seb.sebserver.webservice.servicelayer.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.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamProctoringService;
@ -41,46 +41,48 @@ public interface ExamAdminService {
* @return Result refer to the restriction flag or to an error when happened */
Result<Boolean> isRestricted(Exam exam);
/** Get ExamProctoring data for a certain exam to an error when happened.
/** Get the proctoring service settings for a certain exam to an error when happened.
*
* @param examId the exam instance
* @return Result refer to ExamProctoring data for the exam. */
default Result<ProctoringSettings> getExamProctoringSettings(final Exam exam) {
* @return Result refer to proctoring service settings for the exam. */
default Result<ProctoringServiceSettings> getProctoringServiceSettings(final Exam exam) {
if (exam == null || exam.id == null) {
return Result.ofRuntimeError("Invalid Exam model");
}
return getExamProctoringSettings(exam.id);
return getProctoringServiceSettings(exam.id);
}
/** Get ExamProctoring data for a certain exam to an error when happened.
/** Get proctoring service settings for a certain exam to an error when happened.
*
* @param examId the exam identifier
* @return Result refer to ExamProctoring data for the exam. */
Result<ProctoringSettings> getExamProctoringSettings(Long examId);
* @return Result refer to proctoring service settings for the exam. */
Result<ProctoringServiceSettings> getProctoringServiceSettings(Long examId);
/** Save the given ExamProctoring data for an existing Exam.
/** Save the given proctoring service settings for an existing Exam.
*
* @param examId the exam identifier
* @param examProctoring The ExamProctoring data to save for the exam
* @return Result refer to saved ExamProctoring data or to an error when happened. */
Result<ProctoringSettings> saveExamProctoringSettings(Long examId, ProctoringSettings examProctoring);
* @param examProctoring The proctoring service settings to save for the exam
* @return Result refer to saved proctoring service settings or to an error when happened. */
Result<ProctoringServiceSettings> saveProctoringServiceSettings(
Long examId,
ProctoringServiceSettings examProctoring);
/** This indicates if proctoring is set and enabled for a certain exam.
*
* @param examId the exam instance
* @return Result refer to proctoring is enabled flag or to an error when happened. */
default Result<Boolean> isExamProctoringEnabled(final Exam exam) {
default Result<Boolean> isProctoringEnabled(final Exam exam) {
if (exam == null || exam.id == null) {
return Result.ofRuntimeError("Invalid Exam model");
}
return isExamProctoringEnabled(exam.id);
return isProctoringEnabled(exam.id);
}
/** This indicates if proctoring is set and enabled for a certain exam.
*
* @param examId the exam identifier
* @return Result refer to proctoring is enabled flag or to an error when happened. */
Result<Boolean> isExamProctoringEnabled(final Long examId);
Result<Boolean> isProctoringEnabled(final Long examId);
/** Get the exam proctoring service implementation of specified type.
*
@ -92,18 +94,25 @@ public interface ExamAdminService {
*
* @param settings the ProctoringSettings that defines the ProctoringServerType
* @return ExamProctoringService instance */
default Result<ExamProctoringService> getExamProctoringService(final ProctoringSettings settings) {
default Result<ExamProctoringService> getExamProctoringService(final ProctoringServiceSettings settings) {
return Result.tryCatch(() -> getExamProctoringService(settings.serverType).getOrThrow());
}
/** Get the exam proctoring service implementation for specified exam.
*
* @param exam the exam instance
* @return ExamProctoringService instance */
default Result<ExamProctoringService> getExamProctoringService(final Exam exam) {
return Result.tryCatch(() -> getExamProctoringService(exam.id).getOrThrow());
}
/** Get the exam proctoring service implementation for specified exam.
*
* @param examId the exam identifier
* @return ExamProctoringService instance */
default Result<ExamProctoringService> getExamProctoringService(final Long examId) {
return getExamProctoringSettings(examId)
return getProctoringServiceSettings(examId)
.flatMap(this::getExamProctoringService);
}
}

View file

@ -31,8 +31,8 @@ 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.IndicatorType;
import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSEBRestriction;
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.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
@ -186,64 +186,64 @@ public class ExamAdminServiceImpl implements ExamAdminService {
}
@Override
public Result<ProctoringSettings> getExamProctoringSettings(final Long examId) {
public Result<ProctoringServiceSettings> getProctoringServiceSettings(final Long examId) {
return this.additionalAttributesDAO.getAdditionalAttributes(EntityType.EXAM, examId)
.map(attrs -> attrs.stream()
.collect(Collectors.toMap(
attr -> attr.getName(),
Function.identity())))
.map(mapping -> {
return new ProctoringSettings(
return new ProctoringServiceSettings(
examId,
getEnabled(mapping),
getServerType(mapping),
getString(mapping, ProctoringSettings.ATTR_SERVER_URL),
getString(mapping, ProctoringServiceSettings.ATTR_SERVER_URL),
getCollectingRoomSize(mapping),
getString(mapping, ProctoringSettings.ATTR_APP_KEY),
getString(mapping, ProctoringSettings.ATTR_APP_SECRET));
getString(mapping, ProctoringServiceSettings.ATTR_APP_KEY),
getString(mapping, ProctoringServiceSettings.ATTR_APP_SECRET));
});
}
@Override
@Transactional
public Result<ProctoringSettings> saveExamProctoringSettings(final Long examId,
final ProctoringSettings examProctoring) {
public Result<ProctoringServiceSettings> saveProctoringServiceSettings(final Long examId,
final ProctoringServiceSettings examProctoring) {
return Result.tryCatch(() -> {
this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_ENABLE_PROCTORING,
ProctoringServiceSettings.ATTR_ENABLE_PROCTORING,
String.valueOf(examProctoring.enableProctoring));
this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_SERVER_TYPE,
ProctoringServiceSettings.ATTR_SERVER_TYPE,
examProctoring.serverType.name());
this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_SERVER_URL,
ProctoringServiceSettings.ATTR_SERVER_URL,
examProctoring.serverURL);
this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE,
ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE,
String.valueOf(examProctoring.collectingRoomSize));
this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_APP_KEY,
ProctoringServiceSettings.ATTR_APP_KEY,
examProctoring.appKey);
this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_APP_SECRET,
ProctoringServiceSettings.ATTR_APP_SECRET,
this.cryptor.encrypt(examProctoring.appSecret).toString());
return examProctoring;
@ -251,11 +251,11 @@ public class ExamAdminServiceImpl implements ExamAdminService {
}
@Override
public Result<Boolean> isExamProctoringEnabled(final Long examId) {
public Result<Boolean> isProctoringEnabled(final Long examId) {
final Result<Boolean> result = this.additionalAttributesDAO.getAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_ENABLE_PROCTORING)
ProctoringServiceSettings.ATTR_ENABLE_PROCTORING)
.map(rec -> BooleanUtils.toBoolean(rec.getValue()));
if (result.hasError()) {
return Result.of(false);
@ -270,16 +270,16 @@ public class ExamAdminServiceImpl implements ExamAdminService {
}
private Boolean getEnabled(final Map<String, AdditionalAttributeRecord> mapping) {
if (mapping.containsKey(ProctoringSettings.ATTR_ENABLE_PROCTORING)) {
return BooleanUtils.toBoolean(mapping.get(ProctoringSettings.ATTR_ENABLE_PROCTORING).getValue());
if (mapping.containsKey(ProctoringServiceSettings.ATTR_ENABLE_PROCTORING)) {
return BooleanUtils.toBoolean(mapping.get(ProctoringServiceSettings.ATTR_ENABLE_PROCTORING).getValue());
} else {
return false;
}
}
private ProctoringServerType getServerType(final Map<String, AdditionalAttributeRecord> mapping) {
if (mapping.containsKey(ProctoringSettings.ATTR_SERVER_TYPE)) {
return ProctoringServerType.valueOf(mapping.get(ProctoringSettings.ATTR_SERVER_TYPE).getValue());
if (mapping.containsKey(ProctoringServiceSettings.ATTR_SERVER_TYPE)) {
return ProctoringServerType.valueOf(mapping.get(ProctoringServiceSettings.ATTR_SERVER_TYPE).getValue());
} else {
return ProctoringServerType.JITSI_MEET;
}
@ -294,8 +294,8 @@ public class ExamAdminServiceImpl implements ExamAdminService {
}
private Integer getCollectingRoomSize(final Map<String, AdditionalAttributeRecord> mapping) {
if (mapping.containsKey(ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE)) {
return Integer.valueOf(mapping.get(ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE).getValue());
if (mapping.containsKey(ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE)) {
return Integer.valueOf(mapping.get(ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE).getValue());
} else {
return 20;
}

View file

@ -8,17 +8,14 @@
package ch.ethz.seb.sebserver.webservice.servicelayer.session;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.Collection;
import org.apache.commons.lang3.StringUtils;
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.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gbl.util.Utils;
public interface ExamProctoringService {
@ -31,21 +28,50 @@ public interface ExamProctoringService {
*
* @param examProctoring the settings to test
* @return Result refer to true if the settings are correct and the proctoring server can be accessed. */
Result<Boolean> testExamProctoring(final ProctoringSettings examProctoring);
Result<Boolean> testExamProctoring(final ProctoringServiceSettings examProctoring);
Result<SEBProctoringConnection> getProctorRoomConnection(
ProctoringSettings proctoringSettings,
/** Gets the room connection data for a certain room for the proctor.
*
* @param proctoringSettings the proctoring service settings
* @param roomName the name of the room
* @param subject the subject of the room
* @return Result refer to the room connection data for the proctor to connect to specified room or to an error when
* happened */
Result<ProctoringRoomConnection> getProctorRoomConnection(
ProctoringServiceSettings proctoringSettings,
String roomName,
String subject);
Result<SEBProctoringConnection> sendJoinRoomToClients(
ProctoringSettings proctoringSettings,
/** This instructs all sepcified SEB clients to join a defined room by creating a individual room access token
* and join instruction for each client and put this instruction to the clients instruction queue.
*
* @param proctoringSettings The proctoring service settings
* @param clientConnectionTokens A collection of SEB connection tokens. Only active SEB clients will get the
* instructions
* @param roomName The name of the room to join
* @param subject the subject of the room to join
* @return Result refer to the room connection data for the proctor to join to room too or to an error when
* happened */
Result<ProctoringRoomConnection> sendJoinRoomToClients(
ProctoringServiceSettings proctoringSettings,
Collection<String> clientConnectionTokens,
String roomName,
String subject);
/** Sends instructions to join or rejoin the individual assigned collecting rooms of each involved SEB client.
* Creates an individual join instruction for each involved client and put that to the clients instruction queue.
*
* INFO:
* A collecting room is assigned to each SEB client connection while connecting to the SEB server and
* each SEB client that has successfully connected to the SEB Server and is participating in an exam
* with proctoring enabled, is assigned to a collecting room.
*
* @param proctoringSettings he proctoring service settings
* @param clientConnectionTokens A collection of SEB connection tokens. Only active SEB clients will get the
* instructions
* @return Empty Result that refers to an error when happened */
Result<Void> sendJoinCollectingRoomToClients(
ProctoringSettings proctoringSettings,
ProctoringServiceSettings proctoringSettings,
Collection<String> clientConnectionTokens);
default String verifyRoomName(final String requestedRoomName, final String connectionToken) {
@ -53,49 +79,7 @@ public interface ExamProctoringService {
return requestedRoomName;
}
final Encoder urlEncoder = Base64.getUrlEncoder().withoutPadding();
return urlEncoder.encodeToString(
Utils.toByteArray(connectionToken));
throw new RuntimeException("Test Why: " + connectionToken);
}
// /** Used to get the proctor's room connection data.
// *
// * @param proctoringSettings the proctoring settings
// * @param roomName the name of the room
// * @param subject name of the room
// * @return SEBProctoringConnectionData that contains all connection data */
// Result<SEBProctoringConnection> createProctorPublicRoomConnection(
// final ProctoringSettings proctoringSettings,
// final String roomName,
// final String subject);
//
// Result<SEBProctoringConnection> getClientExamCollectingRoomConnection(
// final ProctoringSettings proctoringSettings,
// final ClientConnection connection);
//
// Result<SEBProctoringConnection> getClientExamCollectingRoomConnection(
// final ProctoringSettings proctoringSettings,
// final String connectionToken,
// final String roomName,
// final String subject);
//
// Result<SEBProctoringConnection> getClientRoomConnection(
// final ProctoringSettings examProctoring,
// final String connectionToken,
// final String roomName,
// final String subject);
//
// Result<SEBProctoringConnection> createProctoringConnection(
// final ProctoringServerType proctoringServerType,
// final String connectionToken,
// final String url,
// final String appKey,
// final CharSequence appSecret,
// final String clientName,
// final String clientKey,
// final String roomName,
// final String subject,
// final Long expTime,
// final boolean moderator);
}

View file

@ -29,9 +29,9 @@ import org.springframework.web.util.UriComponentsBuilder;
import ch.ethz.seb.sebserver.gbl.Constants;
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.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType;
@ -84,14 +84,14 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
}
@Override
public Result<Boolean> testExamProctoring(final ProctoringSettings examProctoring) {
public Result<Boolean> testExamProctoring(final ProctoringServiceSettings examProctoring) {
// TODO Auto-generated method stub
return null;
}
@Override
public Result<SEBProctoringConnection> getProctorRoomConnection(
final ProctoringSettings proctoringSettings,
public Result<ProctoringRoomConnection> getProctorRoomConnection(
final ProctoringServiceSettings proctoringSettings,
final String roomName,
final String subject) {
@ -102,8 +102,8 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
}
@Override
public Result<SEBProctoringConnection> sendJoinRoomToClients(
final ProctoringSettings proctoringSettings,
public Result<ProctoringRoomConnection> sendJoinRoomToClients(
final ProctoringServiceSettings proctoringSettings,
final Collection<String> clientConnectionTokens,
final String roomName,
final String subject) {
@ -112,7 +112,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
clientConnectionTokens
.stream()
.forEach(connectionToken -> {
final SEBProctoringConnection proctoringConnection =
final ProctoringRoomConnection proctoringConnection =
getClientRoomConnection(
proctoringSettings,
connectionToken,
@ -141,7 +141,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
@Override
public Result<Void> sendJoinCollectingRoomToClients(
final ProctoringSettings proctoringSettings,
final ProctoringServiceSettings proctoringSettings,
final Collection<String> clientConnectionTokens) {
return Result.tryCatch(() -> {
@ -155,7 +155,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
.getRoomName(clientConnection.clientConnection.getRemoteProctoringRoomId())
.getOrThrow();
final SEBProctoringConnection proctoringConnection = getClientExamCollectingRoomConnection(
final ProctoringRoomConnection proctoringConnection = getClientExamCollectingRoomConnection(
proctoringSettings,
clientConnection.clientConnection.connectionToken,
roomName,
@ -173,13 +173,13 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
private void sendJoinInstruction(
final Long examId,
final String connectionToken,
final SEBProctoringConnection proctoringConnection) {
final ProctoringRoomConnection proctoringConnection) {
final Map<String, String> attributes = new HashMap<>();
attributes.put(
ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_PROCTORING.SERVICE_TYPE,
ProctoringSettings.ProctoringServerType.JITSI_MEET.name());
ProctoringServiceSettings.ProctoringServerType.JITSI_MEET.name());
attributes.put(
ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_PROCTORING.METHOD,
ClientInstruction.ProctoringInstructionMethod.JOIN.name());
@ -207,8 +207,8 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
.onError(error -> log.error("Failed to send join instruction: {}", connectionToken, error));
}
private Result<SEBProctoringConnection> createProctorPublicRoomConnection(
final ProctoringSettings proctoringSettings,
private Result<ProctoringRoomConnection> createProctorPublicRoomConnection(
final ProctoringServiceSettings proctoringSettings,
final String roomName,
final String subject) {
@ -229,8 +229,8 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
});
}
private Result<SEBProctoringConnection> getClientExamCollectingRoomConnection(
final ProctoringSettings proctoringSettings,
private Result<ProctoringRoomConnection> getClientExamCollectingRoomConnection(
final ProctoringServiceSettings proctoringSettings,
final String connectionToken,
final String roomName,
final String subject) {
@ -256,8 +256,8 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
});
}
private Result<SEBProctoringConnection> getClientRoomConnection(
final ProctoringSettings proctoringSettings,
private Result<ProctoringRoomConnection> getClientRoomConnection(
final ProctoringServiceSettings proctoringSettings,
final String connectionToken,
final String roomName,
final String subject) {
@ -286,7 +286,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
}
protected Result<SEBProctoringConnection> createProctoringConnection(
protected Result<ProctoringRoomConnection> createProctoringConnection(
final ProctoringServerType proctoringServerType,
final String connectionToken,
final String url,
@ -316,7 +316,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
host,
moderator);
return new SEBProctoringConnection(
return new ProctoringRoomConnection(
proctoringServerType,
connectionToken,
host,
@ -385,7 +385,7 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
return jwtPayload;
}
private long forExam(final ProctoringSettings examProctoring) {
private long forExam(final ProctoringServiceSettings examProctoring) {
if (examProctoring.examId == null) {
throw new IllegalStateException("Missing exam identifier from ExamProctoring data");
}

View file

@ -17,7 +17,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
import ch.ethz.seb.sebserver.gbl.model.session.RemoteProctoringRoom;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
@ -71,11 +71,13 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService
@Override
public void updateProctoringCollectingRooms() {
try {
// Applying to collecting room
this.clientConnectionDAO.getAllConnectionIdsForRoomUpdateActive()
.getOrThrow()
.stream()
.forEach(this::assignToCollectingRoom);
// Dispose form collecting room
this.clientConnectionDAO.getAllConnectionIdsForRoomUpdateInactive()
.getOrThrow()
.stream()
@ -156,8 +158,8 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService
private RemoteProctoringRoom getProctoringRoom(final Long examId, final String connectionToken) {
try {
final ProctoringSettings proctoringSettings = this.examAdminService
.getExamProctoringSettings(examId)
final ProctoringServiceSettings proctoringSettings = this.examAdminService
.getProctoringServiceSettings(examId)
.getOrThrow();
return this.remoteProctoringRoomDAO.reservePlaceInCollectingRoom(
examId,
@ -181,7 +183,7 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService
final String subject) {
return this.examAdminService
.getExamProctoringSettings(examId)
.getProctoringServiceSettings(examId)
.flatMap(proctoringSettings -> this.examAdminService
.getExamProctoringService(proctoringSettings.serverType)
.getOrThrow()

View file

@ -16,7 +16,7 @@ import java.util.stream.Collectors;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamProctoringService;

View file

@ -307,7 +307,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
}
final Boolean proctoringEnabled = this.examAdminService
.isExamProctoringEnabled(clientConnection.examId)
.isProctoringEnabled(clientConnection.examId)
.getOr(false);
final Long currentExamId = (examId != null) ? examId : clientConnection.examId;
final String currentVdiConnectionId = (clientId != null)
@ -714,7 +714,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
private ClientConnection saveInState(final ClientConnection clientConnection, final ConnectionStatus status) {
final Boolean proctoringEnabled = this.examAdminService
.isExamProctoringEnabled(clientConnection.examId)
.isProctoringEnabled(clientConnection.examId)
.getOr(false);
return this.clientConnectionDAO.save(new ClientConnection(

View file

@ -13,13 +13,13 @@ import javax.validation.ConstraintValidatorContext;
import org.apache.commons.lang3.StringUtils;
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.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
public class ProctoringSettingsValidator implements ConstraintValidator<ValidProctoringSettings, ProctoringSettings> {
public class ProctoringSettingsValidator implements ConstraintValidator<ValidProctoringSettings, ProctoringServiceSettings> {
@Override
public boolean isValid(final ProctoringSettings value, final ConstraintValidatorContext context) {
public boolean isValid(final ProctoringServiceSettings value, final ConstraintValidatorContext context) {
if (value == null) {
return false;
}

View file

@ -50,7 +50,7 @@ import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
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.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBRestriction;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
@ -386,7 +386,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
+ API.EXAM_ADMINISTRATION_PROCTORING_PATH_SEGMENT,
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ProctoringSettings getExamProctoring(
public ProctoringServiceSettings getProctoringServiceSettings(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
@ -396,7 +396,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
checkReadPrivilege(institutionId);
return this.entityDAO.byPK(modelId)
.flatMap(this.authorization::checkRead)
.flatMap(this.examAdminService::getExamProctoringSettings)
.flatMap(this.examAdminService::getProctoringServiceSettings)
.getOrThrow();
}
@ -405,19 +405,19 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
+ API.EXAM_ADMINISTRATION_PROCTORING_PATH_SEGMENT,
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
public Exam saveExamProctoring(
public Exam saveProctoringServiceSettings(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
@PathVariable(API.PARAM_MODEL_ID) final Long examId,
@Valid @RequestBody final ProctoringSettings examProctoring) {
@Valid @RequestBody final ProctoringServiceSettings examProctoring) {
checkModifyPrivilege(institutionId);
return this.entityDAO.byPK(examId)
.flatMap(this.authorization::checkModify)
.map(exam -> {
this.examAdminService.saveExamProctoringSettings(examId, examProctoring);
this.examAdminService.saveProctoringServiceSettings(examId, examProctoring);
return exam;
})
.flatMap(this.userActivityLogDAO::logModify)

View file

@ -30,8 +30,8 @@ import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
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.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
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.InstructionType;
@ -90,7 +90,7 @@ public class ExamProctoringController {
method = RequestMethod.GET,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public Collection<RemoteProctoringRoom> getProcotringCollectingRoomsOfExam(
public Collection<RemoteProctoringRoom> getCollectingRoomsOfExam(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
@ -108,14 +108,14 @@ public class ExamProctoringController {
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public SEBProctoringConnection getProctorRoomConnection(
public ProctoringRoomConnection getProctorRoomConnection(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
@RequestParam(name = SEBProctoringConnection.ATTR_ROOM_NAME, required = true) final String roomName,
@RequestParam(name = SEBProctoringConnection.ATTR_SUBJECT, required = false) final String subject) {
@RequestParam(name = ProctoringRoomConnection.ATTR_ROOM_NAME, required = true) final String roomName,
@RequestParam(name = ProctoringRoomConnection.ATTR_SUBJECT, required = false) final String subject) {
checkAccess(institutionId, examId);
@ -123,7 +123,7 @@ public class ExamProctoringController {
.flatMap(this.authorization::checkRead)
.flatMap(this.examAdminService::getExamProctoringService)
.flatMap(service -> service.getProctorRoomConnection(
this.examAdminService.getExamProctoringSettings(examId).getOrThrow(),
this.examAdminService.getProctoringServiceSettings(examId).getOrThrow(),
roomName,
StringUtils.isNoneBlank(subject) ? subject : roomName))
.getOrThrow();
@ -135,7 +135,7 @@ public class ExamProctoringController {
method = RequestMethod.GET,
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
public Collection<ClientConnection> getProctorRoomConnectionData(
public Collection<ClientConnection> getAllClientConnectionsInRoom(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
@ -147,7 +147,8 @@ public class ExamProctoringController {
checkAccess(institutionId, examId);
return this.examProcotringRoomService.getRoomConnections(examId, roomName)
return this.examProcotringRoomService
.getRoomConnections(examId, roomName)
.getOrThrow();
}
@ -215,9 +216,9 @@ public class ExamProctoringController {
checkAccess(institutionId, examId);
final ProctoringSettings proctoringSettings = this.examSessionService
final ProctoringServiceSettings proctoringSettings = this.examSessionService
.getRunningExam(examId)
.flatMap(this.examAdminService::getExamProctoringSettings)
.flatMap(this.examAdminService::getProctoringServiceSettings)
.getOrThrow();
this.examAdminService
@ -235,17 +236,17 @@ public class ExamProctoringController {
+ API.EXAM_PROCTORING_JOIN_ROOM_PATH_SEGMENT,
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
public SEBProctoringConnection sendJoinProctoringRoomToClients(
public ProctoringRoomConnection sendJoinProctoringRoomToClients(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
@RequestParam(
name = SEBProctoringConnection.ATTR_ROOM_NAME,
name = ProctoringRoomConnection.ATTR_ROOM_NAME,
required = true) final String roomName,
@RequestParam(
name = SEBProctoringConnection.ATTR_SUBJECT,
name = ProctoringRoomConnection.ATTR_SUBJECT,
required = false) final String subject,
@RequestParam(
name = API.EXAM_API_SEB_CONNECTION_TOKEN,
@ -253,9 +254,9 @@ public class ExamProctoringController {
checkAccess(institutionId, examId);
final ProctoringSettings settings = this.examSessionService
final ProctoringServiceSettings settings = this.examSessionService
.getRunningExam(examId)
.flatMap(this.examAdminService::getExamProctoringSettings)
.flatMap(this.examAdminService::getProctoringServiceSettings)
.getOrThrow();
return this.examAdminService
@ -275,7 +276,7 @@ public class ExamProctoringController {
+ API.EXAM_PROCTORING_TOWNHALL_ROOM_DATA,
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public RemoteProctoringRoom getTownhallRoomData(
public RemoteProctoringRoom getTownhallRoom(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
@ -293,21 +294,21 @@ public class ExamProctoringController {
+ API.EXAM_PROCTORING_ACTIVATE_TOWNHALL_ROOM,
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
public SEBProctoringConnection activateTownhall(
public ProctoringRoomConnection activateTownhall(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
@PathVariable(name = API.PARAM_MODEL_ID) final Long examId,
@RequestParam(
name = SEBProctoringConnection.ATTR_SUBJECT,
name = ProctoringRoomConnection.ATTR_SUBJECT,
required = false) final String subject) {
checkAccess(institutionId, examId);
final ProctoringSettings settings = this.examSessionService
final ProctoringServiceSettings settings = this.examSessionService
.getRunningExam(examId)
.flatMap(this.examAdminService::getExamProctoringSettings)
.flatMap(this.examAdminService::getProctoringServiceSettings)
.getOrThrow();
// First create and get the town-hall room for specified exam
@ -345,9 +346,9 @@ public class ExamProctoringController {
checkAccess(institutionId, examId);
final ProctoringSettings settings = this.examSessionService
final ProctoringServiceSettings settings = this.examSessionService
.getRunningExam(examId)
.flatMap(this.examAdminService::getExamProctoringSettings)
.flatMap(this.examAdminService::getProctoringServiceSettings)
.getOrThrow();
final ExamProctoringService examProctoringService = this.examAdminService

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package ch.ethz.seb.sebserver.webservice.integration.api.admin;
import static org.junit.Assert.*;
import java.util.Collection;
import org.junit.Test;
import org.junit.jupiter.api.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.jdbc.Sql;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientConnectionDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamProctoringRoomService;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
public class ExamProctoringRoomServiceTest extends AdministrationAPIIntegrationTester {
private static final String CONNECTION_TOKEN_1 = "connection_token1";
private static final String CONNECTION_TOKEN_2 = "connection_token2";
@Autowired
private ExamProctoringRoomService examProctoringRoomService;
@Autowired
private ExamSessionService examSessionService;
@Autowired
private ExamAdminService examAdminService;
@Autowired
private ClientConnectionDAO clientConnectionDAO;
@Test
@Order(1)
public void test01_checkExamRunning() {
final Result<Collection<Exam>> runningExamsForInstitution =
this.examSessionService.getRunningExamsForInstitution(1L);
assertFalse(runningExamsForInstitution.hasError());
final Collection<Exam> collection = runningExamsForInstitution.get();
assertFalse(collection.isEmpty());
final Exam exam = collection.iterator().next();
assertEquals("Demo Quiz 6 (MOCKUP)", exam.name);
assertEquals("2", String.valueOf(exam.id));
}
@Test
@Order(2)
public void test02_setProctoringServiceSettings() {
this.examAdminService.saveProctoringServiceSettings(
2L,
new ProctoringServiceSettings(
2L, true, ProctoringServerType.JITSI_MEET, "http://jitsi.ch", 1,
"app-key", "app.secret"));
assertTrue(this.examAdminService.isProctoringEnabled(2L).get());
}
// @Test
// @Order(3)
// public void test03_addClientConnection() {
// clientConnectionDAO.createNew(new ClientConnection(null, 1L, 2L, ConnectionStatus.CONNECTION_REQUESTED, CONNECTION_TOKEN_1))
// }
}

View file

@ -17,8 +17,8 @@ import java.security.NoSuchAlgorithmException;
import org.junit.Test;
import org.mockito.Mockito;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.SEBProctoringConnection;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
public class ExamJITSIProctoringServiceTest {
@ -63,7 +63,7 @@ public class ExamJITSIProctoringServiceTest {
Mockito.when(cryptorMock.decrypt(Mockito.any())).thenReturn("fbvgeghergrgrthrehreg123");
final ExamJITSIProctoringService examJITSIProctoringService =
new ExamJITSIProctoringService(null, null, null, null, cryptorMock);
final SEBProctoringConnection data = examJITSIProctoringService.createProctoringConnection(
final ProctoringRoomConnection data = examJITSIProctoringService.createProctoringConnection(
ProctoringServerType.JITSI_MEET,
"connectionToken",
"https://seb-jitsi.example.ch",