simplified LMS API
This commit is contained in:
parent
0d8fb4b880
commit
0b00995aa7
13 changed files with 117 additions and 230 deletions
|
@ -37,8 +37,6 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam, Exam>, BulkActionSup
|
|||
* happened */
|
||||
Result<GrantEntity> examGrantEntityByClientConnection(Long connectionId);
|
||||
|
||||
Result<Exam> getWithQuizDataFromCache(Long id);
|
||||
|
||||
/** Get all active Exams for a given institution.
|
||||
*
|
||||
* @param institutionId the identifier of the institution
|
||||
|
|
|
@ -392,7 +392,7 @@ public class ExamConfigurationMapDAOImpl implements ExamConfigurationMapDAO {
|
|||
final String status = config.getStatus();
|
||||
|
||||
final Exam exam = this.examDAO
|
||||
.getWithQuizDataFromCache(record.getExamId())
|
||||
.byPK(record.getExamId())
|
||||
.getOr(null);
|
||||
|
||||
return new ExamConfigurationMap(
|
||||
|
|
|
@ -119,13 +119,6 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
.map(record -> toDomainModel(record, null, null).getOrThrow());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Exam> getWithQuizDataFromCache(final Long id) {
|
||||
return recordById(id)
|
||||
.flatMap(this::toDomainModelFromCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Collection<Exam>> all(final Long institutionId, final Boolean active) {
|
||||
|
@ -169,7 +162,6 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final boolean cached = filterMap.getBoolean(Exam.FILTER_CACHED_QUIZZES);
|
||||
final String name = filterMap.getQuizName();
|
||||
final DateTime from = filterMap.getExamFromTime();
|
||||
final Predicate<Exam> quizDataFilter = exam -> {
|
||||
|
@ -236,7 +228,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
.build()
|
||||
.execute();
|
||||
|
||||
return this.toDomainModel(records, cached)
|
||||
return this.toDomainModel(records)
|
||||
.getOrThrow()
|
||||
.stream()
|
||||
.filter(quizDataFilter.and(predicate))
|
||||
|
@ -768,17 +760,6 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
exam.getDescription());
|
||||
}
|
||||
|
||||
private Result<Exam> toDomainModelFromCache(final ExamRecord record) {
|
||||
|
||||
return this.lmsAPIService
|
||||
.getLmsAPITemplate(record.getLmsSetupId())
|
||||
.flatMap(template -> this.toDomainModel(
|
||||
record,
|
||||
template.getQuizFromCache(record.getExternalId())
|
||||
.getOrThrow(),
|
||||
null));
|
||||
}
|
||||
|
||||
private Result<Exam> toDomainModel(final ExamRecord record) {
|
||||
return toDomainModel(
|
||||
record.getLmsSetupId(),
|
||||
|
@ -787,12 +768,6 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
}
|
||||
|
||||
private Result<Collection<Exam>> toDomainModel(final Collection<ExamRecord> records) {
|
||||
return toDomainModel(records, false);
|
||||
}
|
||||
|
||||
private Result<Collection<Exam>> toDomainModel(
|
||||
final Collection<ExamRecord> records,
|
||||
final boolean cached) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
|
@ -807,8 +782,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
.stream()
|
||||
.flatMap(entry -> toDomainModel(
|
||||
entry.getKey(),
|
||||
entry.getValue(),
|
||||
cached)
|
||||
entry.getValue())
|
||||
.onError(error -> log.error(
|
||||
"Failed to get quizzes from LMS Setup: {}",
|
||||
entry.getKey(), error))
|
||||
|
@ -822,14 +796,6 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
final Long lmsSetupId,
|
||||
final Collection<ExamRecord> records) {
|
||||
|
||||
return toDomainModel(lmsSetupId, records, false);
|
||||
}
|
||||
|
||||
private Result<Collection<Exam>> toDomainModel(
|
||||
final Long lmsSetupId,
|
||||
final Collection<ExamRecord> records,
|
||||
final boolean cached) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
// map records
|
||||
|
@ -840,7 +806,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
// get and map quizzes
|
||||
final Map<String, QuizData> quizzes = this.lmsAPIService
|
||||
.getLmsAPITemplate(lmsSetupId)
|
||||
.map(template -> getQuizzesFromLMS(template, recordMapping.keySet(), cached))
|
||||
.map(template -> getQuizzesFromLMS(template, recordMapping.keySet()))
|
||||
.onError(error -> log.error("Failed to get quizzes for exams: ", error))
|
||||
.getOr(Collections.emptyList())
|
||||
.stream()
|
||||
|
@ -894,13 +860,10 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
|
||||
private Collection<Result<QuizData>> getQuizzesFromLMS(
|
||||
final LmsAPITemplate template,
|
||||
final Set<String> ids,
|
||||
final boolean cached) {
|
||||
final Set<String> ids) {
|
||||
|
||||
try {
|
||||
return (cached)
|
||||
? template.getQuizzesFromCache(ids)
|
||||
: template.getQuizzes(ids);
|
||||
return template.getQuizzes(ids);
|
||||
} catch (final Exception e) {
|
||||
log.error("Unexpected error while using LmsAPITemplate to get quizzes: ", e);
|
||||
return Collections.emptyList();
|
||||
|
|
|
@ -8,15 +8,10 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.async.MemoizingCircuitBreaker;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
|
@ -27,7 +22,6 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
|||
import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCourseAccess;
|
||||
|
||||
/** Defines an LMS API access template to build SEB Server LMS integration.
|
||||
|
@ -135,41 +129,10 @@ public interface LmsAPITemplate {
|
|||
|
||||
/** Get the quiz data with specified identifier.
|
||||
*
|
||||
* Default implementation: Uses {@link #getQuizzes(Set<String> ids) } and returns the first matching or an error.
|
||||
*
|
||||
* @param id the quiz data identifier
|
||||
* @return Result refer to the quiz data or to an error when happened */
|
||||
default Result<QuizData> getQuiz(final String id) {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
return Result.ofError(new RuntimeException("missing model id"));
|
||||
}
|
||||
|
||||
return getQuizzes(new HashSet<>(Arrays.asList(id)))
|
||||
.stream()
|
||||
.findFirst()
|
||||
.orElse(Result.ofError(new ResourceNotFoundException(EntityType.EXAM, id)));
|
||||
}
|
||||
|
||||
/** Get all {@link QuizData } for the set of {@link QuizData }-identifiers (ids) from the LMS defined within the
|
||||
* underling LmsSetup, in a collection of Results.
|
||||
*
|
||||
* If there is caching involved this function shall try to get the data from the cache first.
|
||||
*
|
||||
* NOTE: This function depends on the specific LMS implementation and on whether caching the quiz data
|
||||
* makes sense or not. Following strategy is recommended:
|
||||
* Looks first in the cache if the whole set of {@link QuizData } can be get from the cache.
|
||||
* If all quizzes are cached, returns all from cache.
|
||||
* If one or more quiz is not in the cache, requests all quizzes from the API and refreshes the cache
|
||||
*
|
||||
* @param ids the Set of Quiz identifiers to get the {@link QuizData } for
|
||||
* @return Collection of all {@link QuizData } from the given id set */
|
||||
Collection<Result<QuizData>> getQuizzesFromCache(Set<String> ids);
|
||||
|
||||
/** Get a particular quiz data from cache if available. If not, tries to get it from the LMS.
|
||||
*
|
||||
* @param id the quiz identifier, external identifier of the exam.
|
||||
* @return Result refer to the {@link QuizData } or to an error when happended */
|
||||
Result<QuizData> getQuizFromCache(String id);
|
||||
Result<QuizData> getQuiz(final String id);
|
||||
|
||||
/** Clears the underling caches if there are some for a particular implementation. */
|
||||
void clearCache();
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -21,7 +19,6 @@ import org.springframework.core.env.Environment;
|
|||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.async.AsyncService;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
||||
/** This implements an overall short time cache for QuizData objects for all implementing
|
||||
* instances. It uses EH-Cache with a short time to live about 1 - 2 minutes.
|
||||
|
@ -97,11 +94,6 @@ public abstract class AbstractCachedCourseAccess extends AbstractCourseAccess {
|
|||
this.cache.evict(createCacheKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Collection<Result<QuizData>>> getQuizzesFromCache(final Set<String> ids) {
|
||||
return Result.of(ids.stream().map(this::getQuizFromCache).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
/** Get the LMS setup identifier that is wrapped within the implementing template.
|
||||
* This is used to create the cache Key.
|
||||
*
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -135,28 +134,6 @@ public abstract class AbstractCourseAccess {
|
|||
Collections.emptyMap());
|
||||
}
|
||||
|
||||
/** This abstraction has no cache implementation and therefore this returns a Result
|
||||
* with an "No cache supported error.
|
||||
* </p>
|
||||
* To implement and use caching, this must be overridden and implemented
|
||||
*
|
||||
* @param id The identifier of the QuizData to get from cache
|
||||
* @return Result with an "No cache supported error */
|
||||
public Result<QuizData> getQuizFromCache(final String id) {
|
||||
return Result.ofRuntimeError("No cache supported");
|
||||
}
|
||||
|
||||
/** This abstraction has no cache implementation and therefore this returns a Result
|
||||
* with an "No cache supported error.
|
||||
* </p>
|
||||
* To implement and use caching, this must be overridden and implemented
|
||||
*
|
||||
* @param ids Collection of quiz data identifier to get from the cache
|
||||
* @return Result with an "No cache supported error */
|
||||
public Result<Collection<Result<QuizData>>> getQuizzesFromCache(final Set<String> ids) {
|
||||
return Result.ofRuntimeError("No cache supported");
|
||||
}
|
||||
|
||||
/** Provides a supplier for the quiz data request to use within the circuit breaker */
|
||||
protected abstract Supplier<List<QuizData>> quizzesSupplier(final Set<String> ids);
|
||||
|
||||
|
|
|
@ -12,9 +12,12 @@ import java.net.URL;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -195,29 +198,52 @@ final class OpenEdxCourseAccess extends AbstractCachedCourseAccess {
|
|||
.getOrThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<QuizData> getQuizFromCache(final String id) {
|
||||
return Result.tryCatch(() -> {
|
||||
public Collection<Result<QuizData>> getQuizzesFromCache(final Set<String> ids) {
|
||||
final HashSet<String> leftIds = new HashSet<>(ids);
|
||||
final Collection<Result<QuizData>> result = new ArrayList<>();
|
||||
ids.stream()
|
||||
.map(this::getQuizFromCache)
|
||||
.forEach(q -> {
|
||||
if (q != null) {
|
||||
leftIds.remove(q.id);
|
||||
result.add(Result.of(q));
|
||||
}
|
||||
});
|
||||
|
||||
// first try to get it from short time cache
|
||||
QuizData quizData = super.getFromCache(id);
|
||||
if (quizData != null) {
|
||||
return quizData;
|
||||
}
|
||||
if (!leftIds.isEmpty()) {
|
||||
super.quizzesRequest.protectedRun(this.quizzesSupplier(leftIds))
|
||||
.onError(error -> log.error("Failed to get quizzes by ids: ", error))
|
||||
.getOrElse(() -> Collections.emptyList())
|
||||
.stream()
|
||||
.forEach(q -> {
|
||||
leftIds.remove(q.id);
|
||||
result.add(Result.of(q));
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise get one course from LMS and cache
|
||||
final LmsSetup lmsSetup = getApiTemplateDataSupplier().getLmsSetup();
|
||||
final String externalStartURI = getExternalLMSServerAddress(lmsSetup);
|
||||
quizData = quizDataOf(
|
||||
lmsSetup,
|
||||
this.getOneCourse(id, this.restTemplate, id),
|
||||
externalStartURI);
|
||||
if (!leftIds.isEmpty()) {
|
||||
leftIds.forEach(q -> result.add(Result.ofError(new NoSuchElementException())));
|
||||
}
|
||||
|
||||
if (quizData != null) {
|
||||
super.putToCache(quizData);
|
||||
}
|
||||
return quizData;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public QuizData getQuizFromCache(final String id) {
|
||||
return super.getFromCache(id);
|
||||
}
|
||||
|
||||
public QuizData getQuizFromLMS(final String id) {
|
||||
final LmsSetup lmsSetup = getApiTemplateDataSupplier().getLmsSetup();
|
||||
final String externalStartURI = getExternalLMSServerAddress(lmsSetup);
|
||||
final QuizData quizData = quizDataOf(
|
||||
lmsSetup,
|
||||
this.getOneCourse(id, this.restTemplate, id),
|
||||
externalStartURI);
|
||||
|
||||
if (quizData != null) {
|
||||
super.putToCache(quizData);
|
||||
}
|
||||
return quizData;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,9 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.edx;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -82,33 +80,21 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<QuizData> getQuiz(final String id) {
|
||||
return Result.tryCatch(() -> {
|
||||
final QuizData quizFromCache = this.openEdxCourseAccess.getQuizFromCache(id);
|
||||
if (quizFromCache != null) {
|
||||
return quizFromCache;
|
||||
}
|
||||
|
||||
return this.openEdxCourseAccess.getQuizFromLMS(id);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Result<QuizData>> getQuizzes(final Set<String> ids) {
|
||||
final Map<String, QuizData> mapping = this.openEdxCourseAccess
|
||||
.quizzesSupplier(ids)
|
||||
.get()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(qd -> qd.id, Function.identity()));
|
||||
|
||||
return ids.stream()
|
||||
.map(id -> {
|
||||
final QuizData data = mapping.get(id);
|
||||
return (data == null) ? Result.<QuizData> ofRuntimeError("Missing id: " + id) : Result.of(data);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<QuizData> getQuizFromCache(final String id) {
|
||||
return this.openEdxCourseAccess
|
||||
.getQuizFromCache(id)
|
||||
.orElse(() -> getQuiz(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Result<QuizData>> getQuizzesFromCache(final Set<String> ids) {
|
||||
return this.openEdxCourseAccess.getQuizzesFromCache(ids)
|
||||
.getOrElse(() -> getQuizzes(ids));
|
||||
return this.openEdxCourseAccess.getQuizzesFromCache(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.mockup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -164,6 +162,15 @@ public class MockupLmsAPITemplate implements LmsAPITemplate {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<QuizData> getQuiz(final String id) {
|
||||
return Result.of(this.mockups
|
||||
.stream()
|
||||
.filter(q -> id.equals(q.id))
|
||||
.findFirst()
|
||||
.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Result<QuizData>> getQuizzes(final Set<String> ids) {
|
||||
if (!authenticate()) {
|
||||
|
@ -178,16 +185,6 @@ public class MockupLmsAPITemplate implements LmsAPITemplate {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Result<QuizData>> getQuizzesFromCache(final Set<String> ids) {
|
||||
return getQuizzes(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<QuizData> getQuizFromCache(final String id) {
|
||||
return getQuizzes(new HashSet<>(Arrays.asList(id))).iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.function.Function;
|
|||
import java.util.function.Supplier;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -213,7 +214,6 @@ public class MoodleCourseAccess extends AbstractCourseAccess {
|
|||
return LmsSetupTestResult.ofOkay(LmsType.MOODLE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<QuizData> getQuizFromCache(final String id) {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
|
@ -245,43 +245,48 @@ public class MoodleCourseAccess extends AbstractCourseAccess {
|
|||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("No quiz found in cache");
|
||||
// get from LMS
|
||||
final Set<String> ids = Stream.of(id).collect(Collectors.toSet());
|
||||
return super.quizzesRequest
|
||||
.protectedRun(quizzesSupplier(ids))
|
||||
.getOrThrow()
|
||||
.get(0);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Collection<Result<QuizData>>> getQuizzesFromCache(final Set<String> ids) {
|
||||
return Result.tryCatch(() -> {
|
||||
final List<QuizData> cached = getCached();
|
||||
final List<QuizData> available = (cached != null)
|
||||
? cached
|
||||
: Collections.emptyList();
|
||||
public Collection<Result<QuizData>> getQuizzesFromCache(final Set<String> ids) {
|
||||
final List<QuizData> cached = getCached();
|
||||
final List<QuizData> available = (cached != null)
|
||||
? cached
|
||||
: Collections.emptyList();
|
||||
|
||||
final Map<String, QuizData> quizMapping = available
|
||||
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 = super.quizzesRequest
|
||||
.protectedRun(quizzesSupplier(ids))
|
||||
.onError(error -> log.error("Failed to get quizzes by ids: ", error))
|
||||
.getOrElse(() -> Collections.emptyList())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(q -> q.id, Function.identity()));
|
||||
|
||||
if (!quizMapping.keySet().containsAll(ids)) {
|
||||
|
||||
final Map<String, QuizData> collect = quizzesSupplier(ids).get()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(qd -> qd.id, Function.identity()));
|
||||
if (collect != null) {
|
||||
quizMapping.clear();
|
||||
quizMapping.putAll(collect);
|
||||
}
|
||||
.collect(Collectors.toMap(qd -> qd.id, Function.identity()));
|
||||
if (collect != null) {
|
||||
quizMapping.clear();
|
||||
quizMapping.putAll(collect);
|
||||
}
|
||||
}
|
||||
|
||||
return ids
|
||||
.stream()
|
||||
.map(id -> {
|
||||
final QuizData q = quizMapping.get(id);
|
||||
return (q == null)
|
||||
? Result.<QuizData> ofError(new NoSuchElementException("Quiz with id: " + id))
|
||||
: Result.of(q);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
return ids
|
||||
.stream()
|
||||
.map(id -> {
|
||||
final QuizData q = quizMapping.get(id);
|
||||
return (q == null)
|
||||
? Result.<QuizData> ofError(new NoSuchElementException("Quiz with id: " + id))
|
||||
: Result.of(q);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,9 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle;
|
|||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -95,25 +93,13 @@ public class MoodleLmsAPITemplate implements LmsAPITemplate {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Collection<Result<QuizData>> getQuizzes(final Set<String> ids) {
|
||||
final Map<String, QuizData> mapping = this.moodleCourseAccess
|
||||
.quizzesSupplier(ids)
|
||||
.get()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(qd -> qd.id, Function.identity()));
|
||||
|
||||
return ids.stream()
|
||||
.map(id -> {
|
||||
final QuizData data = mapping.get(id);
|
||||
return (data == null) ? Result.<QuizData> ofRuntimeError("Missing id: " + id) : Result.of(data);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
public Result<QuizData> getQuiz(final String id) {
|
||||
return this.moodleCourseAccess.getQuizFromCache(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<QuizData> getQuizFromCache(final String id) {
|
||||
return this.moodleCourseAccess.getQuizFromCache(id)
|
||||
.orElse(() -> getQuiz(id));
|
||||
public Collection<Result<QuizData>> getQuizzes(final Set<String> ids) {
|
||||
return this.moodleCourseAccess.getQuizzesFromCache(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -121,12 +107,6 @@ public class MoodleLmsAPITemplate implements LmsAPITemplate {
|
|||
this.moodleCourseAccess.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Result<QuizData>> getQuizzesFromCache(final Set<String> ids) {
|
||||
return this.moodleCourseAccess.getQuizzesFromCache(ids)
|
||||
.getOrElse(() -> getQuizzes(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Chapters> getCourseChapters(final String courseId) {
|
||||
return Result.tryCatch(() -> this.moodleCourseAccess
|
||||
|
|
|
@ -124,7 +124,7 @@ public class ExamSessionServiceImpl implements ExamSessionService {
|
|||
final Collection<APIMessage> result = new ArrayList<>();
|
||||
|
||||
final Exam exam = this.examDAO
|
||||
.getWithQuizDataFromCache(examId)
|
||||
.byPK(examId)
|
||||
.getOrThrow();
|
||||
|
||||
// check lms connection
|
||||
|
|
|
@ -280,7 +280,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
|
|||
|
||||
checkReadPrivilege(institutionId);
|
||||
return this.examDAO
|
||||
.getWithQuizDataFromCache(modelId)
|
||||
.byPK(modelId)
|
||||
.flatMap(this.examAdminService::isRestricted)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue