Filter fromDate in Moodle lookup
This commit is contained in:
parent
3cefcbe3f3
commit
7fcfcf1445
4 changed files with 44 additions and 10 deletions
|
@ -43,7 +43,7 @@ public abstract class CourseAccess {
|
|||
|
||||
protected CourseAccess(final AsyncService asyncService) {
|
||||
this.allQuizzesRequest = asyncService.createMemoizingCircuitBreaker(
|
||||
allQuizzesSupplier(),
|
||||
allQuizzesSupplier(null),
|
||||
3,
|
||||
Constants.MINUTE_IN_MILLIS,
|
||||
Constants.MINUTE_IN_MILLIS,
|
||||
|
@ -101,6 +101,9 @@ public abstract class CourseAccess {
|
|||
}
|
||||
|
||||
public Result<List<QuizData>> getQuizzes(final FilterMap filterMap) {
|
||||
if (filterMap != null) {
|
||||
this.allQuizzesRequest.setSupplier(allQuizzesSupplier(filterMap));
|
||||
}
|
||||
return this.allQuizzesRequest.get()
|
||||
.map(LmsAPIService.quizzesFilterFunction(filterMap));
|
||||
}
|
||||
|
@ -136,7 +139,7 @@ public abstract class CourseAccess {
|
|||
|
||||
protected abstract Supplier<List<QuizData>> quizzesSupplier(final Set<String> ids);
|
||||
|
||||
protected abstract Supplier<List<QuizData>> allQuizzesSupplier();
|
||||
protected abstract Supplier<List<QuizData>> allQuizzesSupplier(final FilterMap filterMap);
|
||||
|
||||
protected abstract Supplier<Chapters> getCourseChaptersSupplier(final String courseId);
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
|
|||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.CourseAccess;
|
||||
|
||||
/** Implements the LmsAPITemplate for Open edX LMS Course API access.
|
||||
|
@ -173,7 +174,7 @@ final class OpenEdxCourseAccess extends CourseAccess {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<List<QuizData>> allQuizzesSupplier() {
|
||||
protected Supplier<List<QuizData>> allQuizzesSupplier(final FilterMap filterMap) {
|
||||
return () -> getRestTemplate()
|
||||
.map(this::collectAllQuizzes)
|
||||
.getOrThrow();
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.function.Supplier;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
|
@ -40,6 +41,7 @@ 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.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.CourseAccess;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory.MoodleAPIRestTemplate;
|
||||
|
||||
|
@ -48,6 +50,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestT
|
|||
* See also: https://docs.moodle.org/dev/Web_service_API_functions */
|
||||
public class MoodleCourseAccess extends CourseAccess {
|
||||
|
||||
private static final long INITIAL_WAIT_TIME = 3 * Constants.SECOND_IN_MILLIS;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MoodleCourseAccess.class);
|
||||
|
||||
private static final String MOODLE_QUIZ_START_URL_PATH = "mod/quiz/view.php?id=";
|
||||
|
@ -172,9 +176,9 @@ public class MoodleCourseAccess extends CourseAccess {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Supplier<List<QuizData>> allQuizzesSupplier() {
|
||||
protected Supplier<List<QuizData>> allQuizzesSupplier(final FilterMap filterMap) {
|
||||
return () -> getRestTemplate()
|
||||
.map(template -> collectAllQuizzes(template))
|
||||
.map(template -> collectAllQuizzes(template, filterMap))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
@ -183,34 +187,51 @@ public class MoodleCourseAccess extends CourseAccess {
|
|||
throw new UnsupportedOperationException("not available yet");
|
||||
}
|
||||
|
||||
private List<QuizData> collectAllQuizzes(final MoodleAPIRestTemplate restTemplate) {
|
||||
private List<QuizData> collectAllQuizzes(
|
||||
final MoodleAPIRestTemplate restTemplate,
|
||||
final FilterMap filterMap) {
|
||||
|
||||
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;
|
||||
|
||||
final DateTime quizFromTime = (filterMap != null) ? filterMap.getQuizFromTime() : null;
|
||||
final long fromCutTime = (quizFromTime != null) ? Utils.toUnixTimeInSeconds(quizFromTime) : -1;
|
||||
|
||||
Collection<CourseData> courseQuizData = Collections.emptyList();
|
||||
if (this.moodleCourseDataLazyLoader.isRunning()) {
|
||||
courseQuizData = this.moodleCourseDataLazyLoader.getPreFilteredCourseIds();
|
||||
} else if (this.moodleCourseDataLazyLoader.getLastRunTime() <= 0) {
|
||||
// set cut time if available
|
||||
if (fromCutTime >= 0) {
|
||||
this.moodleCourseDataLazyLoader.setFromCutTime(fromCutTime);
|
||||
}
|
||||
// first run async and wait some time, get what is there
|
||||
this.moodleCourseDataLazyLoader.loadAsync(restTemplate);
|
||||
try {
|
||||
Thread.sleep(5 * Constants.SECOND_IN_MILLIS);
|
||||
Thread.sleep(INITIAL_WAIT_TIME);
|
||||
courseQuizData = this.moodleCourseDataLazyLoader.getPreFilteredCourseIds();
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to wait for first load run: ", e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else if (this.moodleCourseDataLazyLoader.isLongRunningTask()) {
|
||||
// kick off the task again when old asynchronously and take back what is there instantly
|
||||
if (Utils.getMillisecondsNow() - this.moodleCourseDataLazyLoader.getLastRunTime() > 10
|
||||
// on long running tasks if we have a different fromCutTime as before
|
||||
// kick off the lazy loadung task imeditially with the new time filter
|
||||
if (fromCutTime > 0 && fromCutTime != this.moodleCourseDataLazyLoader.getFromCutTime()) {
|
||||
this.moodleCourseDataLazyLoader.setFromCutTime(fromCutTime);
|
||||
this.moodleCourseDataLazyLoader.loadAsync(restTemplate);
|
||||
// otherwise kick off only if the last fetch task was then minutes ago
|
||||
} else if (Utils.getMillisecondsNow() - this.moodleCourseDataLazyLoader.getLastRunTime() > 10
|
||||
* Constants.MINUTE_IN_MILLIS) {
|
||||
this.moodleCourseDataLazyLoader.loadAsync(restTemplate);
|
||||
}
|
||||
courseQuizData = this.moodleCourseDataLazyLoader.getPreFilteredCourseIds();
|
||||
} else {
|
||||
// just run the task in sync
|
||||
if (fromCutTime >= 0) {
|
||||
this.moodleCourseDataLazyLoader.setFromCutTime(fromCutTime);
|
||||
}
|
||||
this.moodleCourseDataLazyLoader.loadSync(restTemplate);
|
||||
courseQuizData = this.moodleCourseDataLazyLoader.getPreFilteredCourseIds();
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public class MoodleCourseDataLazyLoader {
|
|||
private long lastLoadTime = 0;
|
||||
private boolean running = false;
|
||||
|
||||
private final long fromCutTime = DateTime.now(DateTimeZone.UTC).minusYears(3).getMillis() / 1000;
|
||||
private long fromCutTime;
|
||||
|
||||
public MoodleCourseDataLazyLoader(
|
||||
final JSONMapper jsonMapper,
|
||||
|
@ -73,6 +73,15 @@ public class MoodleCourseDataLazyLoader {
|
|||
|
||||
this.jsonMapper = jsonMapper;
|
||||
this.asyncRunner = asyncRunner;
|
||||
this.fromCutTime = Utils.toUnixTimeInSeconds(DateTime.now(DateTimeZone.UTC).minusYears(3));
|
||||
}
|
||||
|
||||
public long getFromCutTime() {
|
||||
return this.fromCutTime;
|
||||
}
|
||||
|
||||
public void setFromCutTime(final long fromCutTime) {
|
||||
this.fromCutTime = fromCutTime;
|
||||
}
|
||||
|
||||
public Set<CourseData> getPreFilteredCourseIds() {
|
||||
|
|
Loading…
Add table
Reference in a new issue