Merge remote-tracking branch 'origin/patch-1.0.2' into development

Conflicts:
	src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java
	src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ClientEventController.java
	fixes in Moodle LMS binding
This commit is contained in:
anhefti 2020-10-06 09:08:04 +02:00
commit 3fd064055a
5 changed files with 23 additions and 24 deletions

View file

@ -24,11 +24,19 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam, Exam>, BulkActionSup
/** Get a GrantEntity for the exam of specified id (PK)
* This is actually a Exam instance but with no course data loaded.
*
*
* @param id The id of the exam (PK)
* @return Result referring to the GrantEntity of the exam or to an error when happened */
Result<GrantEntity> examGrantEntityByPK(final Long id);
/** Get an Exam GrantEntity by a given ClientConnection id.
* This is actually a Exam instance but with no course data loaded.
*
* @param connectionId the connection identifier
* @return a Result containing the Exam GrantEntity by a given ClientConnection id or refer to an error if
* happened */
Result<GrantEntity> examGrantEntityByClientConnection(Long connectionId);
/** Get all active Exams for a given institution.
*
* @param institutionId the identifier of the institution
@ -56,12 +64,6 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam, Exam>, BulkActionSup
key = "#exam.id")
Result<Exam> save(Exam exam);
/** Get an Exam by a given ClientConnection id.
*
* @param connectionId the connection identifier
* @return a Result containing the Exam by a given ClientConnection id or refer to an error if happened */
Result<Exam> byClientConnection(Long connectionId);
/** Use this to get identifiers of all exams in a specified state for a specified institution.
*
* @param institutionId the institution identifier. May be null for all institutions

View file

@ -94,12 +94,11 @@ public class ExamDAOImpl implements ExamDAO {
@Override
@Transactional(readOnly = true)
public Result<Exam> byClientConnection(final Long connectionId) {
public Result<GrantEntity> examGrantEntityByClientConnection(final Long connectionId) {
return Result.tryCatch(() -> this.clientConnectionRecordMapper
.selectByPrimaryKey(connectionId))
.flatMap(ccRecord -> recordById(ccRecord.getExamId()))
.flatMap(this::toDomainModelCached)
.onError(TransactionHandler::rollback);
.map(record -> toDomainModel(record, null).getOrThrow());
}
@Override
@ -708,14 +707,6 @@ public class ExamDAOImpl implements ExamDAO {
exam.getDescription());
}
private Result<Exam> toDomainModelCached(final ExamRecord record) {
return Result.tryCatch(() -> this.lmsAPIService
.getLmsAPITemplate(record.getLmsSetupId())
.getOrThrow())
.flatMap(template -> template.getQuizFromCache(record.getExternalId()))
.flatMap(quizData -> this.toDomainModel(record, quizData));
}
private Result<Exam> toDomainModel(final ExamRecord record) {
return toDomainModel(
record.getLmsSetupId(),

View file

@ -18,7 +18,6 @@ import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.coyote.http11.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.LinkedMultiValueMap;
@ -29,6 +28,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.async.AsyncService;
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
@ -48,7 +48,7 @@ public class MoodleCourseAccess extends CourseAccess {
private static final Logger log = LoggerFactory.getLogger(MoodleCourseAccess.class);
private static final String MOODLE_QUIZ_START_URL_PATH = "mod/quiz/view.php?id=";
private static final String MOODLE_QUIZ_START_URL_PATH = "mod/quiz/view.php?q=";
private static final String MOODLE_COURSE_API_FUNCTION_NAME = "core_course_get_courses";
private static final String MOODLE_USER_PROFILE_API_FUNCTION_NAME = "core_user_get_users_by_field";
private static final String MOODLE_QUIZ_API_FUNCTION_NAME = "mod_quiz_get_quizzes_by_courses";
@ -161,7 +161,9 @@ public class MoodleCourseAccess extends CourseAccess {
}
private ArrayList<QuizData> collectAllQuizzes(final MoodleAPIRestTemplate restTemplate) {
final String urlPrefix = this.lmsSetup.lmsApiUrl + MOODLE_QUIZ_START_URL_PATH;
final String urlPrefix = (this.lmsSetup.lmsApiUrl.endsWith(Constants.URL_PATH_SEPARATOR))
? this.lmsSetup.lmsApiUrl + MOODLE_QUIZ_START_URL_PATH
: this.lmsSetup.lmsApiUrl + Constants.URL_PATH_SEPARATOR + MOODLE_QUIZ_START_URL_PATH;
return collectAllCourses(restTemplate)
.stream()
.reduce(
@ -239,7 +241,7 @@ public class MoodleCourseAccess extends CourseAccess {
final List<QuizData> courseAndQuiz = courseData.quizzes
.stream()
.map(courseQuizData -> {
final String startURI = uriPrefix + courseQuizData.course_module;
final String startURI = uriPrefix + courseQuizData.id;
additionalAttrs.put(QuizData.ATTR_ADDITIONAL_TIME_LIMIT, String.valueOf(courseQuizData.time_limit));
return new QuizData(
getInternalQuizId(courseQuizData.id, courseData.short_name, courseData.idnumber),

View file

@ -244,9 +244,13 @@ public class ExamSessionServiceImpl implements ExamSessionService {
.putIfAbsent(Exam.FILTER_ATTR_ACTIVE, Constants.TRUE_STRING)
.putIfAbsent(Exam.FILTER_ATTR_STATUS, ExamStatus.RUNNING.name());
// NOTE: we evict the exam from the cache (if present) to ensure user is seeing always the current state of the Exam
return this.examDAO.allMatching(filterMap, predicate)
.map(col -> col.stream()
.map(exam -> this.examSessionCacheService.getRunningExam(exam.id))
.map(exam -> {
this.examSessionCacheService.evict(exam);
return this.examSessionCacheService.getRunningExam(exam.id);
})
.filter(Objects::nonNull)
.collect(Collectors.toList()));
}

View file

@ -205,7 +205,7 @@ public class ClientEventController extends ReadonlyEntityController<ClientEvent,
@Override
protected GrantEntity toGrantEntity(final ClientEvent entity) {
return this.examDao
.byPK(entity.connectionId)
.examGrantEntityByClientConnection(entity.connectionId)
.get();
}