From bb9d0b068d4b074355015cf2562df592e2ed83d6 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 17 May 2021 09:03:22 +0200 Subject: [PATCH] caching and local tests working --- .../lms/impl/AbstractCachedCourseAccess.java | 14 +---- .../lms/impl/edx/OpenEdxCourseAccess.java | 54 ++++++++++++++++--- src/main/resources/config/ehcache.xml | 18 +++---- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCachedCourseAccess.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCachedCourseAccess.java index 15473d59..baaca1bf 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCachedCourseAccess.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/AbstractCachedCourseAccess.java @@ -21,12 +21,12 @@ 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 overal short time cache for QuizData object for all implementing + * classes. It uses EH-Cache with a short time to live */ public abstract class AbstractCachedCourseAccess extends AbstractCourseAccess { public static final String CACHE_NAME_QUIZ_DATA = "QUIZ_DATA_CACHE"; - private static final String NO_QUIZ_DATA_FOUND_ERROR = "NO_QUIZ_DATA_FOUND_ERROR"; - private final Cache cache; protected AbstractCachedCourseAccess( @@ -58,16 +58,6 @@ public abstract class AbstractCachedCourseAccess extends AbstractCourseAccess { this.cache.evict(createCacheKey(id)); } - @Override - public Result getQuizFromCache(final String id) { - final QuizData fromCache = getFromCache(id); - if (fromCache != null) { - return Result.of(fromCache); - } else { - return Result.ofRuntimeError(NO_QUIZ_DATA_FOUND_ERROR); - } - } - @Override public Result>> getQuizzesFromCache(final Set ids) { return Result.of(ids.stream().map(this::getQuizFromCache).collect(Collectors.toList())); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/edx/OpenEdxCourseAccess.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/edx/OpenEdxCourseAccess.java index 29f705c5..e1edda88 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/edx/OpenEdxCourseAccess.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/edx/OpenEdxCourseAccess.java @@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.edx; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -194,19 +195,53 @@ final class OpenEdxCourseAccess extends AbstractCachedCourseAccess { .getOrThrow(); } + @Override + public Result getQuizFromCache(final String id) { + return Result.tryCatch(() -> { + + // first try to get it from short time cache + QuizData quizData = super.getFromCache(id); + if (quizData != null) { + return quizData; + } + + // 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 (quizData != null) { + super.putToCache(quizData); + } + return quizData; + }); + } + @Override protected Supplier> quizzesSupplier(final Set ids) { if (ids.size() == 1) { return () -> { + + final String id = ids.iterator().next(); + + // first try to get it from short time cache + final QuizData quizData = super.getFromCache(id); + if (quizData != null) { + return Arrays.asList(quizData); + } + final LmsSetup lmsSetup = getApiTemplateDataSupplier().getLmsSetup(); final String externalStartURI = getExternalLMSServerAddress(lmsSetup); return Arrays.asList(quizDataOf( lmsSetup, - getOneCourses( + getOneCourse( lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_ENDPOINT, getRestTemplate().getOrThrow(), - ids), + id), externalStartURI)); }; } else { @@ -301,7 +336,7 @@ final class OpenEdxCourseAccess extends AbstractCachedCourseAccess { private List collectCourses( final String pageURI, final OAuth2RestTemplate restTemplate, - final Set ids) { + final Collection ids) { final List collector = new ArrayList<>(); EdXPage page = getEdxPage(pageURI, restTemplate).getBody(); @@ -324,21 +359,21 @@ final class OpenEdxCourseAccess extends AbstractCachedCourseAccess { return collector; } - private CourseData getOneCourses( + private CourseData getOneCourse( final String pageURI, final OAuth2RestTemplate restTemplate, - final Set ids) { + final String id) { System.out.println("********************"); - // NOTE: try first to get the course data by id. This seems to be possible + // NOTE: try to get the course data by id. This seems to be possible // when the SEB restriction is not set. Once the SEB restriction is set, // this gives a 403 response. // We haven't found another way to get course data by id in this case so far // Workaround is to search the course by paging (slow) try { final HttpHeaders httpHeaders = new HttpHeaders(); - final String uri = pageURI + ids.iterator().next(); + final String uri = pageURI + id; final ResponseEntity exchange = restTemplate.exchange( uri, HttpMethod.GET, @@ -348,7 +383,10 @@ final class OpenEdxCourseAccess extends AbstractCachedCourseAccess { return exchange.getBody(); } catch (final Exception e) { // try with paging - final List collectCourses = collectCourses(pageURI, restTemplate, ids); + final List collectCourses = collectCourses( + pageURI, + restTemplate, + Arrays.asList(id)); if (collectCourses.isEmpty()) { return null; } diff --git a/src/main/resources/config/ehcache.xml b/src/main/resources/config/ehcache.xml index b212c3e2..1d92de07 100644 --- a/src/main/resources/config/ehcache.xml +++ b/src/main/resources/config/ehcache.xml @@ -9,7 +9,7 @@ java.lang.Long ch.ethz.seb.sebserver.gbl.model.exam.Exam - 24 + 24 100 @@ -20,7 +20,7 @@ java.lang.String ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ClientConnectionDataInternal - 24 + 24 3000 @@ -31,7 +31,7 @@ java.lang.Long ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.InMemorySEBConfig - 24 + 24 20 @@ -42,7 +42,7 @@ java.lang.String ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientEventRecord - 24 + 24 2000 @@ -53,7 +53,7 @@ java.lang.Long ch.ethz.seb.sebserver.gbl.util.Result - 24 + 24 100 @@ -64,7 +64,7 @@ org.springframework.security.oauth2.common.OAuth2AccessToken org.springframework.security.oauth2.provider.OAuth2Authentication - 24 + 24 100 @@ -75,7 +75,7 @@ java.lang.String ch.ethz.seb.sebserver.gbl.util.Result - 24 + 24 2000 @@ -86,7 +86,7 @@ java.lang.Long org.ehcache.impl.internal.concurrent.ConcurrentHashMap - 24 + 24 10 @@ -97,7 +97,7 @@ java.lang.String ch.ethz.seb.sebserver.gbl.model.exam.QuizData - 10 + 1 10000