SEBSERV-308 test with Moodle and Open edX and fixes

This commit is contained in:
anhefti 2022-05-24 14:40:47 +02:00
parent 960864e58f
commit e06394258a
7 changed files with 56 additions and 51 deletions

View file

@ -452,14 +452,14 @@ public class ExamForm implements TemplateComposer {
.newAction(ActionDefinition.EXAM_ENABLE_SEB_RESTRICTION)
.withEntityKey(entityKey)
.withExec(action -> this.examSEBRestrictionSettings.setSEBRestriction(action, true, this.restService))
.publishIf(() -> sebRestrictionAvailable && readonly && modifyGrant && !importFromQuizData
.publishIf(() -> sebRestrictionAvailable && readonly && editable && !importFromQuizData
&& BooleanUtils.isFalse(isRestricted))
.newAction(ActionDefinition.EXAM_DISABLE_SEB_RESTRICTION)
.withConfirm(() -> ACTION_MESSAGE_SEB_RESTRICTION_RELEASE)
.withEntityKey(entityKey)
.withExec(action -> this.examSEBRestrictionSettings.setSEBRestriction(action, false, this.restService))
.publishIf(() -> sebRestrictionAvailable && readonly && modifyGrant && !importFromQuizData
.publishIf(() -> sebRestrictionAvailable && readonly && editable && !importFromQuizData
&& BooleanUtils.isTrue(isRestricted))
.newAction(ActionDefinition.EXAM_PROCTORING_ON)

View file

@ -279,7 +279,7 @@ public class ExamList implements TemplateComposer {
return;
}
if (exam.getStatus() == ExamStatus.UP_COMING || exam.getStatus() == ExamStatus.FINISHED) {
if (exam.getStatus() != ExamStatus.RUNNING) {
return;
}

View file

@ -114,7 +114,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
return this.lmsAPIService
.getLmsAPITemplate(exam.lmsSetupId)
.map(lmsAPI -> !lmsAPI.getSEBClientRestriction(exam).hasError());
.map(lmsAPI -> !lmsAPI.hasSEBClientRestriction(exam));
}
@Override

View file

@ -33,6 +33,14 @@ public interface SEBRestrictionAPI {
* missing or to another exception on unexpected error case */
Result<SEBRestriction> getSEBClientRestriction(Exam exam);
/** Use this to check if there is a SEB restriction available on the LMS for the specified exam.
*
* @param exam exam the exam to get the SEB restriction data for
* @return true if there is a SEB restriction set on the LMS for the exam or false otherwise */
default boolean hasSEBClientRestriction(final Exam exam) {
return getSEBClientRestriction(exam).hasError();
}
/** Applies SEB Client restrictions to the LMS with the given attributes.
*
* @param externalExamId The exam/course identifier from LMS side (Exam.externalId)

View file

@ -40,7 +40,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
private static final Logger log = LoggerFactory.getLogger(LmsAPITemplateAdapter.class);
private final CourseAccessAPI courseAccessAPI;
private final SEBRestrictionAPI sebBestrictionAPI;
private final SEBRestrictionAPI sebRestrictionAPI;
private final APITemplateDataSupplier apiTemplateDataSupplier;
/** CircuitBreaker for protected lmsTestRequest */
@ -64,10 +64,10 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
final Environment environment,
final APITemplateDataSupplier apiTemplateDataSupplier,
final CourseAccessAPI courseAccessAPI,
final SEBRestrictionAPI sebBestrictionAPI) {
final SEBRestrictionAPI sebRestrictionAPI) {
this.courseAccessAPI = courseAccessAPI;
this.sebBestrictionAPI = sebBestrictionAPI;
this.sebRestrictionAPI = sebRestrictionAPI;
this.apiTemplateDataSupplier = apiTemplateDataSupplier;
this.lmsTestRequest = asyncService.createCircuitBreaker(
@ -82,7 +82,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.lmsTestRequest.timeToRecover",
Long.class,
Constants.MINUTE_IN_MILLIS));
0L));
this.allQuizzesRequest = asyncService.createCircuitBreaker(
environment.getProperty(
@ -96,7 +96,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover",
Long.class,
Constants.MINUTE_IN_MILLIS));
0L));
this.quizzesRequest = asyncService.createCircuitBreaker(
environment.getProperty(
@ -110,7 +110,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover",
Long.class,
Constants.MINUTE_IN_MILLIS));
0L));
this.quizRequest = asyncService.createCircuitBreaker(
environment.getProperty(
@ -124,7 +124,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.quizzesRequest.timeToRecover",
Long.class,
Constants.MINUTE_IN_MILLIS));
0L));
this.chaptersRequest = asyncService.createCircuitBreaker(
environment.getProperty(
@ -138,7 +138,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.chaptersRequest.timeToRecover",
Long.class,
Constants.SECOND_IN_MILLIS * 30));
0L));
this.accountDetailRequest = asyncService.createCircuitBreaker(
environment.getProperty(
@ -152,7 +152,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.accountDetailRequest.timeToRecover",
Long.class,
Constants.SECOND_IN_MILLIS * 30));
0L));
this.restrictionRequest = asyncService.createCircuitBreaker(
environment.getProperty(
@ -166,7 +166,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.sebrestriction.timeToRecover",
Long.class,
Constants.SECOND_IN_MILLIS * 30));
0L));
this.releaseRestrictionRequest = asyncService.createCircuitBreaker(
environment.getProperty(
@ -180,7 +180,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
environment.getProperty(
"sebserver.webservice.circuitbreaker.sebrestriction.timeToRecover",
Long.class,
Constants.SECOND_IN_MILLIS * 30));
0L));
}
@Override
@ -363,8 +363,8 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
@Override
public LmsSetupTestResult testCourseRestrictionAPI() {
if (this.sebBestrictionAPI != null) {
return this.sebBestrictionAPI.testCourseRestrictionAPI();
if (this.sebRestrictionAPI != null) {
return this.sebRestrictionAPI.testCourseRestrictionAPI();
}
if (log.isDebugEnabled()) {
@ -377,7 +377,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
@Override
public Result<SEBRestriction> getSEBClientRestriction(final Exam exam) {
if (this.sebBestrictionAPI == null) {
if (this.sebRestrictionAPI == null) {
return Result.ofError(
new UnsupportedOperationException("SEB Restriction API Not Supported For: " + getType().name()));
}
@ -386,7 +386,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
log.debug("Get course restriction: {} for LMSSetup: {}", exam.externalId, lmsSetup());
}
return this.restrictionRequest.protectedRun(() -> this.sebBestrictionAPI
return this.restrictionRequest.protectedRun(() -> this.sebRestrictionAPI
.getSEBClientRestriction(exam)
.onError(error -> log.error(
"Failed to get SEB restrictions: {}",
@ -394,12 +394,22 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
.getOrThrow());
}
@Override
public boolean hasSEBClientRestriction(final Exam exam) {
if (this.sebRestrictionAPI == null) {
return false;
}
return this.sebRestrictionAPI
.getSEBClientRestriction(exam).hasError();
}
@Override
public Result<SEBRestriction> applySEBClientRestriction(
final String externalExamId,
final SEBRestriction sebRestrictionData) {
if (this.sebBestrictionAPI == null) {
if (this.sebRestrictionAPI == null) {
return Result.ofError(
new UnsupportedOperationException("SEB Restriction API Not Supported For: " + getType().name()));
}
@ -408,7 +418,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
log.debug("Apply course restriction: {} for LMSSetup: {}", externalExamId, lmsSetup());
}
return this.restrictionRequest.protectedRun(() -> this.sebBestrictionAPI
return this.restrictionRequest.protectedRun(() -> this.sebRestrictionAPI
.applySEBClientRestriction(externalExamId, sebRestrictionData)
.onError(error -> log.error(
"Failed to apply SEB restrictions: {}",
@ -419,7 +429,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
@Override
public Result<Exam> releaseSEBClientRestriction(final Exam exam) {
if (this.sebBestrictionAPI == null) {
if (this.sebRestrictionAPI == null) {
return Result.ofError(
new UnsupportedOperationException("SEB Restriction API Not Supported For: " + getType().name()));
}
@ -428,7 +438,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
log.debug("Release course restriction: {} for LMSSetup: {}", exam.externalId, lmsSetup());
}
return this.releaseRestrictionRequest.protectedRun(() -> this.sebBestrictionAPI
return this.releaseRestrictionRequest.protectedRun(() -> this.sebRestrictionAPI
.releaseSEBClientRestriction(exam)
.onError(error -> log.error(
"Failed to release SEB restrictions: {}",

View file

@ -248,13 +248,19 @@ public class SEBRestrictionServiceImpl implements SEBRestrictionService {
@Override
public Result<Exam> releaseSEBClientRestriction(final Exam exam) {
if (log.isDebugEnabled()) {
log.debug(" *** SEB Restriction *** Release SEB Client restrictions from LMS for exam: {}", exam);
}
return this.lmsAPIService
.getLmsAPITemplate(exam.lmsSetupId)
.flatMap(template -> template.releaseSEBClientRestriction(exam));
.map(template -> {
if (template.lmsSetup().lmsType.features.contains(Features.SEB_RESTRICTION)) {
if (log.isDebugEnabled()) {
log.debug(" *** SEB Restriction *** Release SEB Client restrictions from LMS for exam: {}",
exam);
}
template.releaseSEBClientRestriction(exam);
}
return exam;
});
}
}

View file

@ -156,30 +156,11 @@ public class MoodleCourseAccess implements CourseAccessAPI {
@Override
public Result<Collection<QuizData>> getQuizzes(final Set<String> ids) {
return Result.tryCatch(() -> {
final List<QuizData> cached = getCached();
final List<QuizData> available = (cached != null)
? cached
: Collections.emptyList();
final Map<String, QuizData> quizMapping = available
.stream()
.collect(Collectors.toMap(q -> q.id, Function.identity()));
if (!quizMapping.keySet().containsAll(ids)) {
final Map<String, QuizData> collect = getRestTemplate()
.map(template -> getQuizzesForIds(template, ids))
.getOrElse(() -> Collections.emptyList())
.stream()
.collect(Collectors.toMap(qd -> qd.id, Function.identity()));
if (collect != null) {
quizMapping.clear();
quizMapping.putAll(collect);
}
}
return quizMapping.values();
return getRestTemplate()
.map(template -> getQuizzesForIds(template, ids))
.onError(error -> log.error("Failed to get courses for: {}", ids, error))
.getOrElse(() -> Collections.emptyList());
});
}