disallow proctoring service change if there are existing proctoring
rooms
This commit is contained in:
parent
8381b5d621
commit
d2036a8598
7 changed files with 57 additions and 32 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue