diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java b/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java index 10da7d76..593f4520 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java @@ -569,7 +569,7 @@ public final class Utils { return (hexString.length() < 2) ? "0" + hexString : hexString; } - public static String toJsonArrayValue(final Map attributes) { + public static String toJsonObject(final Map attributes) { if (attributes == null || attributes.isEmpty()) { return StringUtils.EMPTY; } @@ -578,7 +578,7 @@ public final class Utils { .entrySet() .stream() .reduce( - new StringBuilder(), + new StringBuilder(Constants.CURLY_BRACE_OPEN), (sb, entry) -> sb .append(Constants.DOUBLE_QUOTE) .append(entry.getKey()) @@ -588,7 +588,8 @@ public final class Utils { .append(entry.getValue()) .append(Constants.DOUBLE_QUOTE) .append(Constants.COMMA), - StringBuilder::append); + StringBuilder::append) + .append(Constants.CURLY_BRACE_CLOSE); if (builder.length() > 0) { return builder diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/table/StaticListPageSupplier.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/StaticListPageSupplier.java index 6745ae59..98181232 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/table/StaticListPageSupplier.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/StaticListPageSupplier.java @@ -19,6 +19,10 @@ import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.PageSortOrder; import ch.ethz.seb.sebserver.gbl.util.Result; +/** This implements a page supplier within a static list. + * Currently ordering and filtering is not possible and must be implemented. + * + * @param the type of the list/page elements */ public class StaticListPageSupplier implements PageSupplier { private final EntityType entityType; @@ -45,6 +49,7 @@ public class StaticListPageSupplier implements PageSupplier { private int pageNumber; private int pageSize; private String column; + @SuppressWarnings("unused") private PageSortOrder order; private StaticListTableBuilderAdapter(final List list) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java index 361051a4..1f904657 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java @@ -315,7 +315,7 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO { .build() .execute() .stream() - .filter(cc -> ConnectionStatus.ACTIVE.name() == cc.getStatus()) + .filter(cc -> ConnectionStatus.ACTIVE.name().equals(cc.getStatus())) .map(ClientConnectionRecord::getConnectionToken) .collect(Collectors.toSet())); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamAdminServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamAdminServiceImpl.java index 01199727..adb1aaff 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamAdminServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamAdminServiceImpl.java @@ -28,11 +28,11 @@ import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.JSONMapper; 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.ServerType; 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.ServerType; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; @@ -214,11 +214,15 @@ public class ExamAdminServiceImpl implements ExamAdminService { @Override public Result isExamProctoringEnabled(final Long examId) { - return this.additionalAttributesDAO.getAdditionalAttribute( + final Result result = this.additionalAttributesDAO.getAdditionalAttribute( EntityType.EXAM, examId, ProctoringSettings.ATTR_ENABLE_PROCTORING) - .map(rec -> rec != null && BooleanUtils.toBoolean(rec.getValue())); + .map(rec -> BooleanUtils.toBoolean(rec.getValue())); + if (result.hasError()) { + return Result.of(false); + } + return result; } @Override diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java index a1e81cf0..64065161 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java @@ -400,7 +400,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic } catch (final Exception e) { log.error( "Failed to process proctoring initialization for established SEB client connection: {}", - clientConnection.connectionToken); + clientConnection.connectionToken, e); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBInstructionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBInstructionServiceImpl.java index 98bca872..b284ab78 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBInstructionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBInstructionServiceImpl.java @@ -25,6 +25,7 @@ import org.springframework.stereotype.Service; import ch.ethz.seb.sebserver.SEBServerInit; import ch.ethz.seb.sebserver.SEBServerInitEvent; import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.api.JSONMapper; import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.InstructionType; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; @@ -96,16 +97,24 @@ public class SEBInstructionServiceImpl implements SEBInstructionService { final boolean needsConfirm) { return Result.tryCatch(() -> { + final boolean isActive = this.clientConnectionDAO .isActiveConnection(examId, connectionToken) .getOr(false); if (isActive) { - final String attributesString = Utils.toJsonArrayValue(attributes); - this.clientInstructionDAO - .insert(examId, type, attributesString, connectionToken, needsConfirm) - .map(inst -> this.instructions.putIfAbsent(inst.getConnectionToken(), inst)) - .onError(error -> log.error("Failed to put instruction: ", error)) - .getOrThrow(); + try { + final String attributesString = new JSONMapper().writeValueAsString(attributes); + this.clientInstructionDAO + .insert(examId, type, attributesString, connectionToken, needsConfirm) + .map(inst -> { + this.instructions.putIfAbsent(inst.getConnectionToken(), inst); + return inst; + }) + .onError(error -> log.error("Failed to put instruction: ", error)) + .getOrThrow(); + } catch (final Exception e) { + throw new RuntimeException("Unexpected: ", e); + } } }); } @@ -120,7 +129,7 @@ public class SEBInstructionServiceImpl implements SEBInstructionService { return Result.tryCatch(() -> { - final String attributesString = Utils.toJsonArrayValue(attributes); + final String attributesString = Utils.toJsonObject(attributes); final Set activeConnections = this.clientConnectionDAO .filterActive(examId, connectionTokens) .getOrElse(Collections::emptySet); @@ -177,9 +186,7 @@ public class SEBInstructionServiceImpl implements SEBInstructionService { .append(JSON_ATTR) .append(Constants.DOUBLE_QUOTE) .append(Constants.COLON) - .append(Constants.CURLY_BRACE_OPEN) - .append(attributes) - .append(Constants.CURLY_BRACE_CLOSE); + .append(attributes); } return sBuilder diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java index bd279f6b..e0367431 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java @@ -282,16 +282,16 @@ public class ExamAPI_V1_Controller { final String pingNumString = request.getParameter(API.EXAM_API_PING_NUMBER); final String instructionConfirm = request.getParameter(API.EXAM_API_PING_INSTRUCTION_CONFIRM); + if (instructionConfirm != null) { + this.sebClientConnectionService.confirmInstructionDone(connectionToken, instructionConfirm); + } + final String instruction = this.sebClientConnectionService .notifyPing( connectionToken, Long.parseLong(timeStampString), pingNumString != null ? Integer.parseInt(pingNumString) : -1); - if (instructionConfirm != null) { - this.sebClientConnectionService.confirmInstructionDone(connectionToken, instructionConfirm); - } - if (instruction == null) { response.setStatus(HttpStatus.NO_CONTENT.value()); return;