SEBSERV-139 TestBot integration and testing and fixes
This commit is contained in:
parent
65cdb1dc52
commit
6980715e2f
7 changed files with 40 additions and 23 deletions
|
@ -569,7 +569,7 @@ public final class Utils {
|
||||||
return (hexString.length() < 2) ? "0" + hexString : hexString;
|
return (hexString.length() < 2) ? "0" + hexString : hexString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String toJsonArrayValue(final Map<String, String> attributes) {
|
public static String toJsonObject(final Map<String, String> attributes) {
|
||||||
if (attributes == null || attributes.isEmpty()) {
|
if (attributes == null || attributes.isEmpty()) {
|
||||||
return StringUtils.EMPTY;
|
return StringUtils.EMPTY;
|
||||||
}
|
}
|
||||||
|
@ -578,7 +578,7 @@ public final class Utils {
|
||||||
.entrySet()
|
.entrySet()
|
||||||
.stream()
|
.stream()
|
||||||
.reduce(
|
.reduce(
|
||||||
new StringBuilder(),
|
new StringBuilder(Constants.CURLY_BRACE_OPEN),
|
||||||
(sb, entry) -> sb
|
(sb, entry) -> sb
|
||||||
.append(Constants.DOUBLE_QUOTE)
|
.append(Constants.DOUBLE_QUOTE)
|
||||||
.append(entry.getKey())
|
.append(entry.getKey())
|
||||||
|
@ -588,7 +588,8 @@ public final class Utils {
|
||||||
.append(entry.getValue())
|
.append(entry.getValue())
|
||||||
.append(Constants.DOUBLE_QUOTE)
|
.append(Constants.DOUBLE_QUOTE)
|
||||||
.append(Constants.COMMA),
|
.append(Constants.COMMA),
|
||||||
StringBuilder::append);
|
StringBuilder::append)
|
||||||
|
.append(Constants.CURLY_BRACE_CLOSE);
|
||||||
|
|
||||||
if (builder.length() > 0) {
|
if (builder.length() > 0) {
|
||||||
return builder
|
return builder
|
||||||
|
|
|
@ -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.model.PageSortOrder;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
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 <T> the type of the list/page elements */
|
||||||
public class StaticListPageSupplier<T> implements PageSupplier<T> {
|
public class StaticListPageSupplier<T> implements PageSupplier<T> {
|
||||||
|
|
||||||
private final EntityType entityType;
|
private final EntityType entityType;
|
||||||
|
@ -45,6 +49,7 @@ public class StaticListPageSupplier<T> implements PageSupplier<T> {
|
||||||
private int pageNumber;
|
private int pageNumber;
|
||||||
private int pageSize;
|
private int pageSize;
|
||||||
private String column;
|
private String column;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
private PageSortOrder order;
|
private PageSortOrder order;
|
||||||
|
|
||||||
private StaticListTableBuilderAdapter(final List<T> list) {
|
private StaticListTableBuilderAdapter(final List<T> list) {
|
||||||
|
|
|
@ -315,7 +315,7 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO {
|
||||||
.build()
|
.build()
|
||||||
.execute()
|
.execute()
|
||||||
.stream()
|
.stream()
|
||||||
.filter(cc -> ConnectionStatus.ACTIVE.name() == cc.getStatus())
|
.filter(cc -> ConnectionStatus.ACTIVE.name().equals(cc.getStatus()))
|
||||||
.map(ClientConnectionRecord::getConnectionToken)
|
.map(ClientConnectionRecord::getConnectionToken)
|
||||||
.collect(Collectors.toSet()));
|
.collect(Collectors.toSet()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
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.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;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
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.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;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
@ -214,11 +214,15 @@ public class ExamAdminServiceImpl implements ExamAdminService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<Boolean> isExamProctoringEnabled(final Long examId) {
|
public Result<Boolean> isExamProctoringEnabled(final Long examId) {
|
||||||
return this.additionalAttributesDAO.getAdditionalAttribute(
|
final Result<Boolean> result = this.additionalAttributesDAO.getAdditionalAttribute(
|
||||||
EntityType.EXAM,
|
EntityType.EXAM,
|
||||||
examId,
|
examId,
|
||||||
ProctoringSettings.ATTR_ENABLE_PROCTORING)
|
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
|
@Override
|
||||||
|
|
|
@ -400,7 +400,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
log.error(
|
log.error(
|
||||||
"Failed to process proctoring initialization for established SEB client connection: {}",
|
"Failed to process proctoring initialization for established SEB client connection: {}",
|
||||||
clientConnection.connectionToken);
|
clientConnection.connectionToken, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.springframework.stereotype.Service;
|
||||||
import ch.ethz.seb.sebserver.SEBServerInit;
|
import ch.ethz.seb.sebserver.SEBServerInit;
|
||||||
import ch.ethz.seb.sebserver.SEBServerInitEvent;
|
import ch.ethz.seb.sebserver.SEBServerInitEvent;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
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.model.session.ClientInstruction.InstructionType;
|
||||||
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;
|
||||||
|
@ -96,16 +97,24 @@ public class SEBInstructionServiceImpl implements SEBInstructionService {
|
||||||
final boolean needsConfirm) {
|
final boolean needsConfirm) {
|
||||||
|
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
|
|
||||||
final boolean isActive = this.clientConnectionDAO
|
final boolean isActive = this.clientConnectionDAO
|
||||||
.isActiveConnection(examId, connectionToken)
|
.isActiveConnection(examId, connectionToken)
|
||||||
.getOr(false);
|
.getOr(false);
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
final String attributesString = Utils.toJsonArrayValue(attributes);
|
try {
|
||||||
|
final String attributesString = new JSONMapper().writeValueAsString(attributes);
|
||||||
this.clientInstructionDAO
|
this.clientInstructionDAO
|
||||||
.insert(examId, type, attributesString, connectionToken, needsConfirm)
|
.insert(examId, type, attributesString, connectionToken, needsConfirm)
|
||||||
.map(inst -> this.instructions.putIfAbsent(inst.getConnectionToken(), inst))
|
.map(inst -> {
|
||||||
|
this.instructions.putIfAbsent(inst.getConnectionToken(), inst);
|
||||||
|
return inst;
|
||||||
|
})
|
||||||
.onError(error -> log.error("Failed to put instruction: ", error))
|
.onError(error -> log.error("Failed to put instruction: ", error))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new RuntimeException("Unexpected: ", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -120,7 +129,7 @@ public class SEBInstructionServiceImpl implements SEBInstructionService {
|
||||||
|
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
|
|
||||||
final String attributesString = Utils.toJsonArrayValue(attributes);
|
final String attributesString = Utils.toJsonObject(attributes);
|
||||||
final Set<String> activeConnections = this.clientConnectionDAO
|
final Set<String> activeConnections = this.clientConnectionDAO
|
||||||
.filterActive(examId, connectionTokens)
|
.filterActive(examId, connectionTokens)
|
||||||
.getOrElse(Collections::emptySet);
|
.getOrElse(Collections::emptySet);
|
||||||
|
@ -177,9 +186,7 @@ public class SEBInstructionServiceImpl implements SEBInstructionService {
|
||||||
.append(JSON_ATTR)
|
.append(JSON_ATTR)
|
||||||
.append(Constants.DOUBLE_QUOTE)
|
.append(Constants.DOUBLE_QUOTE)
|
||||||
.append(Constants.COLON)
|
.append(Constants.COLON)
|
||||||
.append(Constants.CURLY_BRACE_OPEN)
|
.append(attributes);
|
||||||
.append(attributes)
|
|
||||||
.append(Constants.CURLY_BRACE_CLOSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sBuilder
|
return sBuilder
|
||||||
|
|
|
@ -282,16 +282,16 @@ public class ExamAPI_V1_Controller {
|
||||||
final String pingNumString = request.getParameter(API.EXAM_API_PING_NUMBER);
|
final String pingNumString = request.getParameter(API.EXAM_API_PING_NUMBER);
|
||||||
final String instructionConfirm = request.getParameter(API.EXAM_API_PING_INSTRUCTION_CONFIRM);
|
final String instructionConfirm = request.getParameter(API.EXAM_API_PING_INSTRUCTION_CONFIRM);
|
||||||
|
|
||||||
|
if (instructionConfirm != null) {
|
||||||
|
this.sebClientConnectionService.confirmInstructionDone(connectionToken, instructionConfirm);
|
||||||
|
}
|
||||||
|
|
||||||
final String instruction = this.sebClientConnectionService
|
final String instruction = this.sebClientConnectionService
|
||||||
.notifyPing(
|
.notifyPing(
|
||||||
connectionToken,
|
connectionToken,
|
||||||
Long.parseLong(timeStampString),
|
Long.parseLong(timeStampString),
|
||||||
pingNumString != null ? Integer.parseInt(pingNumString) : -1);
|
pingNumString != null ? Integer.parseInt(pingNumString) : -1);
|
||||||
|
|
||||||
if (instructionConfirm != null) {
|
|
||||||
this.sebClientConnectionService.confirmInstructionDone(connectionToken, instructionConfirm);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instruction == null) {
|
if (instruction == null) {
|
||||||
response.setStatus(HttpStatus.NO_CONTENT.value());
|
response.setStatus(HttpStatus.NO_CONTENT.value());
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Reference in a new issue