disallow proctoring service change if there are existing proctoring

rooms
This commit is contained in:
anhefti 2021-06-22 14:26:08 +02:00
parent 8381b5d621
commit d2036a8598
7 changed files with 57 additions and 32 deletions

View file

@ -36,6 +36,7 @@ public class ProctoringServiceSettings implements Entity {
public static final String ATTR_APP_SECRET = "appSecret";
public static final String ATTR_COLLECTING_ROOM_SIZE = "collectingRoomSize";
public static final String ATTR_COLLECT_ALL_ROOM_NAME = "collectAllRoomName";
public static final String ATTR_SERVICE_IN_USE = "serviceInUse";
@JsonProperty(Domain.EXAM.ATTR_ID)
public final Long examId;
@ -59,6 +60,9 @@ public class ProctoringServiceSettings implements Entity {
@JsonProperty(ATTR_COLLECTING_ROOM_SIZE)
public final Integer collectingRoomSize;
@JsonProperty(ATTR_SERVICE_IN_USE)
public final Boolean serviceInUse;
@JsonCreator
public ProctoringServiceSettings(
@JsonProperty(Domain.EXAM.ATTR_ID) final Long examId,
@ -66,6 +70,7 @@ public class ProctoringServiceSettings implements Entity {
@JsonProperty(ATTR_SERVER_TYPE) final ProctoringServerType serverType,
@JsonProperty(ATTR_SERVER_URL) final String serverURL,
@JsonProperty(ATTR_COLLECTING_ROOM_SIZE) final Integer collectingRoomSize,
@JsonProperty(ATTR_SERVICE_IN_USE) final Boolean serviceInUse,
@JsonProperty(ATTR_APP_KEY) final String appKey,
@JsonProperty(ATTR_APP_SECRET) final CharSequence appSecret) {
@ -74,6 +79,7 @@ public class ProctoringServiceSettings implements Entity {
this.serverType = (serverType != null) ? serverType : ProctoringServerType.JITSI_MEET;
this.serverURL = serverURL;
this.collectingRoomSize = (collectingRoomSize != null) ? collectingRoomSize : 20;
this.serviceInUse = serviceInUse;
this.appKey = appKey;
this.appSecret = appSecret;
}
@ -121,6 +127,10 @@ public class ProctoringServiceSettings implements Entity {
return this.appSecret;
}
public Boolean getServiceInUse() {
return this.serviceInUse;
}
@Override
public int hashCode() {
final int prime = 31;

View file

@ -128,8 +128,8 @@ public class ExamProctoringSettings {
final boolean enabled = BooleanUtils.toBoolean(
form.getFieldValue(ProctoringServiceSettings.ATTR_ENABLE_PROCTORING));
final ProctoringServerType serverType = ProctoringServerType.valueOf(
form.getFieldValue(ProctoringServiceSettings.ATTR_SERVER_TYPE));
final ProctoringServerType serverType = ProctoringServerType
.valueOf(form.getFieldValue(ProctoringServiceSettings.ATTR_SERVER_TYPE));
examProctoring = new ProctoringServiceSettings(
Long.parseLong(entityKey.modelId),
@ -137,6 +137,7 @@ public class ExamProctoringSettings {
serverType,
form.getFieldValue(ProctoringServiceSettings.ATTR_SERVER_URL),
Integer.parseInt(form.getFieldValue(ProctoringServiceSettings.ATTR_COLLECTING_ROOM_SIZE)),
false,
form.getFieldValue(ProctoringServiceSettings.ATTR_APP_KEY),
form.getFieldValue(ProctoringServiceSettings.ATTR_APP_SECRET));
@ -263,6 +264,11 @@ public class ExamProctoringSettings {
.build();
if (proctoringSettings.serviceInUse) {
formHandle.getForm().getFieldInput(ProctoringServiceSettings.ATTR_SERVER_TYPE).setEnabled(false);
formHandle.getForm().getFieldInput(ProctoringServiceSettings.ATTR_SERVER_URL).setEnabled(false);
}
return () -> formHandle;
}
}

View file

@ -19,6 +19,12 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.proctoring.New
/** Data access for RemoteProctoringRoom domain objects. */
public interface RemoteProctoringRoomDAO {
/** Indicates if there is already any proctoring service in use for the specified exam
*
* @param examId the exam identifier
* @return Result refer to the indication or to an error when happened. */
Result<Boolean> isServiceInUse(Long examId);
/** Get all collecting room records that exists for a given exam.
*
* @param examId the exam identifier

View file

@ -56,6 +56,15 @@ public class RemoteProctoringRoomDAOImpl implements RemoteProctoringRoomDAO {
this.remoteProctoringRoomRecordMapper = remoteProctoringRoomRecordMapper;
}
@Override
public Result<Boolean> isServiceInUse(final Long examId) {
return Result.tryCatch(() -> this.remoteProctoringRoomRecordMapper
.countByExample()
.where(RemoteProctoringRoomRecordDynamicSqlSupport.examId, isEqualTo(examId))
.build()
.execute() > 0);
}
@Override
@Transactional(readOnly = true)
public Result<Collection<RemoteProctoringRoom>> getCollectingRooms(final Long examId) {

View file

@ -43,6 +43,7 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.AdditionalAttribut
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.AdditionalAttributesDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.IndicatorDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.RemoteProctoringRoomDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
@ -62,6 +63,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
private final JSONMapper jsonMapper;
private final Cryptor cryptor;
private final ExamProctoringServiceFactory examProctoringServiceFactory;
private final RemoteProctoringRoomDAO remoteProctoringRoomDAO;
private final String defaultIndicatorName;
private final String defaultIndicatorType;
@ -76,6 +78,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
final JSONMapper jsonMapper,
final Cryptor cryptor,
final ExamProctoringServiceFactory examProctoringServiceFactory,
final RemoteProctoringRoomDAO remoteProctoringRoomDAO,
@Value("${sebserver.webservice.api.exam.indicator.name:Ping}") final String defaultIndicatorName,
@Value("${sebserver.webservice.api.exam.indicator.type:LAST_PING}") final String defaultIndicatorType,
@Value("${sebserver.webservice.api.exam.indicator.color:b4b4b4}") final String defaultIndicatorColor,
@ -88,6 +91,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
this.jsonMapper = jsonMapper;
this.cryptor = cryptor;
this.examProctoringServiceFactory = examProctoringServiceFactory;
this.remoteProctoringRoomDAO = remoteProctoringRoomDAO;
this.defaultIndicatorName = defaultIndicatorName;
this.defaultIndicatorType = defaultIndicatorType;
@ -199,6 +203,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
getServerType(mapping),
getString(mapping, ProctoringServiceSettings.ATTR_SERVER_URL),
getCollectingRoomSize(mapping),
this.remoteProctoringRoomDAO.isServiceInUse(examId).getOr(true),
getString(mapping, ProctoringServiceSettings.ATTR_APP_KEY),
getString(mapping, ProctoringServiceSettings.ATTR_APP_SECRET));
});

View file

@ -170,30 +170,6 @@ public class ZoomProctoringService implements ExamProctoringService {
throw new APIMessageException(
APIMessage.ErrorMessage.BINDING_ERROR,
String.valueOf(result.getStatusCode()));
} else {
// TODO this is just for cleaning up along development process.
// Remove this before finish up the Zoom integration
try {
final ProctoringServiceSettings encryptedSettings = new ProctoringServiceSettings(
proctoringSettings.examId,
proctoringSettings.enableProctoring,
proctoringSettings.serverType,
proctoringSettings.serverURL,
proctoringSettings.collectingRoomSize,
proctoringSettings.appKey,
this.cryptor
.encrypt(proctoringSettings.appSecret)
.getOrThrow());
disposeServiceRoomsForExam(
proctoringSettings.examId,
encryptedSettings)
.getOrThrow();
} catch (final Exception e) {
log.error("Failed to dev-cleanup rooms: ", e);
}
}
} catch (final Exception e) {

View file

@ -20,6 +20,8 @@ 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.model.session.ClientConnection;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
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;
@ -60,16 +62,27 @@ public class ExamProctoringRoomServiceTest extends AdministrationAPIIntegrationT
this.examAdminService.saveProctoringServiceSettings(
2L,
new ProctoringServiceSettings(
2L, true, ProctoringServerType.JITSI_MEET, "http://jitsi.ch", 1,
2L, true, ProctoringServerType.JITSI_MEET, "http://jitsi.ch", 1, false,
"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))
// }
@Test
@Order(3)
public void test03_addClientConnection() {
final Result<ClientConnection> createNew = this.clientConnectionDAO.createNew(new ClientConnection(
null,
1L,
2L,
ConnectionStatus.CONNECTION_REQUESTED,
CONNECTION_TOKEN_1,
"",
"",
false,
"",
null));
assertFalse(createNew.hasError());
}
}