SEBSERV-301 moved mockup to test and improved LMSSetup test function
This commit is contained in:
parent
3a86db9ba0
commit
ed180603f8
9 changed files with 64 additions and 431 deletions
|
@ -32,7 +32,8 @@ public final class LmsSetupTestResult {
|
|||
MISSING_ATTRIBUTE,
|
||||
TOKEN_REQUEST,
|
||||
QUIZ_ACCESS_API_REQUEST,
|
||||
QUIZ_RESTRICTION_API_REQUEST
|
||||
QUIZ_RESTRICTION_API_REQUEST,
|
||||
TEMPLATE_CREATION
|
||||
}
|
||||
|
||||
@JsonProperty(Domain.LMS_SETUP.ATTR_LMS_TYPE)
|
||||
|
@ -59,7 +60,7 @@ public final class LmsSetupTestResult {
|
|||
Collections.emptyList());
|
||||
}
|
||||
|
||||
protected LmsSetupTestResult(final LmsSetup.LmsType lmsType, final Error error) {
|
||||
public LmsSetupTestResult(final LmsSetup.LmsType lmsType, final Error error) {
|
||||
this(lmsType,
|
||||
Utils.immutableCollectionOf(Arrays.asList(error)),
|
||||
Collections.emptyList());
|
||||
|
@ -163,7 +164,6 @@ public final class LmsSetupTestResult {
|
|||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -479,6 +479,11 @@ public class LmsSetupForm implements TemplateComposer {
|
|||
Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message))));
|
||||
}
|
||||
case QUIZ_ACCESS_API_REQUEST: {
|
||||
if (error.message.contains("quizaccess_sebserver_get_exams")) {
|
||||
throw new PageMessageException(new LocTextKey(
|
||||
"sebserver.lmssetup.action.test.quizRequestError.moodle.missing.plugin",
|
||||
Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message))));
|
||||
}
|
||||
throw new PageMessageException(new LocTextKey(
|
||||
"sebserver.lmssetup.action.test.quizRequestError",
|
||||
Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message))));
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.springframework.context.event.EventListener;
|
|||
import org.springframework.stereotype.Service;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.client.ClientCredentialService;
|
||||
import ch.ethz.seb.sebserver.gbl.client.ClientCredentials;
|
||||
import ch.ethz.seb.sebserver.gbl.client.ProxyData;
|
||||
|
@ -33,12 +32,12 @@ import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
|||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult.ErrorType;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.LmsSetupDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||
|
@ -133,17 +132,13 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
public Result<LmsAPITemplate> getLmsAPITemplate(final String lmsSetupId) {
|
||||
return Result.tryCatch(() -> {
|
||||
synchronized (this) {
|
||||
LmsAPITemplate lmsAPITemplate = getFromCache(lmsSetupId);
|
||||
final LmsAPITemplate lmsAPITemplate = getFromCache(lmsSetupId);
|
||||
if (lmsAPITemplate == null) {
|
||||
lmsAPITemplate = createLmsSetupTemplate(lmsSetupId);
|
||||
if (lmsAPITemplate != null) {
|
||||
this.cache.put(new CacheKey(lmsSetupId, System.currentTimeMillis()), lmsAPITemplate);
|
||||
}
|
||||
return createLmsSetupTemplate(lmsSetupId)
|
||||
.onError(error -> log.error("Failed to create LMSSetup: ", error))
|
||||
.onSuccess(t -> this.cache.put(new CacheKey(lmsSetupId, System.currentTimeMillis()), t))
|
||||
.getOrThrow();
|
||||
}
|
||||
if (lmsAPITemplate == null) {
|
||||
throw new ResourceNotFoundException(EntityType.LMS_SETUP, lmsSetupId);
|
||||
}
|
||||
|
||||
return lmsAPITemplate;
|
||||
}
|
||||
});
|
||||
|
@ -153,10 +148,12 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
public LmsSetupTestResult test(final LmsAPITemplate template) {
|
||||
final LmsSetupTestResult testCourseAccessAPI = template.testCourseAccessAPI();
|
||||
if (!testCourseAccessAPI.isOk()) {
|
||||
this.cache.remove(new CacheKey(template.lmsSetup().getModelId(), 0));
|
||||
return testCourseAccessAPI;
|
||||
}
|
||||
|
||||
if (template.lmsSetup().getLmsType().features.contains(LmsSetup.Features.SEB_RESTRICTION)) {
|
||||
this.cache.remove(new CacheKey(template.lmsSetup().getModelId(), 0));
|
||||
return template.testCourseRestrictionAPI();
|
||||
}
|
||||
|
||||
|
@ -169,7 +166,15 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
lmsSetup,
|
||||
this.clientCredentialService);
|
||||
|
||||
final LmsAPITemplate lmsSetupTemplate = createLmsSetupTemplate(apiTemplateDataSupplier);
|
||||
final Result<LmsAPITemplate> createLmsSetupTemplate = createLmsSetupTemplate(apiTemplateDataSupplier);
|
||||
if (createLmsSetupTemplate.hasError()) {
|
||||
return new LmsSetupTestResult(
|
||||
lmsSetup.lmsType,
|
||||
new LmsSetupTestResult.Error(ErrorType.TEMPLATE_CREATION,
|
||||
createLmsSetupTemplate.getError().getMessage()));
|
||||
|
||||
}
|
||||
final LmsAPITemplate lmsSetupTemplate = createLmsSetupTemplate.get();
|
||||
|
||||
final LmsSetupTestResult testCourseAccessAPI = lmsSetupTemplate.testCourseAccessAPI();
|
||||
if (!testCourseAccessAPI.isOk()) {
|
||||
|
@ -183,40 +188,6 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
return LmsSetupTestResult.ofOkay(lmsSetupTemplate.lmsSetup().getLmsType());
|
||||
}
|
||||
|
||||
// /** Collect all QuizData from all affecting LmsSetup.
|
||||
// * If filterMap contains a LmsSetup identifier, only the QuizData from that LmsSetup is collected.
|
||||
// * Otherwise QuizData from all active LmsSetup of the current institution are collected.
|
||||
// *
|
||||
// * @param filterMap the FilterMap containing either an LmsSetup identifier or an institution identifier
|
||||
// * @return list of QuizData from all affecting LmsSetup */
|
||||
// private Result<List<QuizData>> getAllQuizzesFromLMSSetups(final FilterMap filterMap) {
|
||||
//
|
||||
// // case 1. if lmsSetupId is available only get quizzes from specified LmsSetup
|
||||
// final Long lmsSetupId = filterMap.getLmsSetupId();
|
||||
// if (lmsSetupId != null) {
|
||||
// return getQuizzesForSingleLMS(filterMap, lmsSetupId);
|
||||
// }
|
||||
//
|
||||
// // case 2. get quizzes from all LmsSetups of specified institution
|
||||
// return this.quizLookupService.getAllQuizzesFromLMSSetups(
|
||||
// filterMap,
|
||||
// this::getLmsAPITemplate);
|
||||
//
|
||||
//// final Long institutionId = filterMap.getInstitutionId();
|
||||
//// return this.lmsSetupDAO.all(institutionId, true)
|
||||
//// .getOrThrow()
|
||||
//// .parallelStream()
|
||||
//// .map(LmsSetup::getModelId)
|
||||
//// .map(this::getLmsAPITemplate)
|
||||
//// .flatMap(Result::onErrorLogAndSkip)
|
||||
//// .map(template -> template.getQuizzes(filterMap))
|
||||
//// .flatMap(Result::onErrorLogAndSkip)
|
||||
//// .flatMap(List::stream)
|
||||
//// .distinct()
|
||||
//// .collect(Collectors.toList());
|
||||
//
|
||||
// }
|
||||
|
||||
private LmsAPITemplate getFromCache(final String lmsSetupId) {
|
||||
// first cleanup the cache by removing old instances
|
||||
final long currentTimeMillis = System.currentTimeMillis();
|
||||
|
@ -245,7 +216,7 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
return lmsAPITemplate;
|
||||
}
|
||||
|
||||
private LmsAPITemplate createLmsSetupTemplate(final String lmsSetupId) {
|
||||
private Result<LmsAPITemplate> createLmsSetupTemplate(final String lmsSetupId) {
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Create new LmsAPITemplate for id: {}", lmsSetupId);
|
||||
|
@ -256,7 +227,7 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
this.lmsSetupDAO));
|
||||
}
|
||||
|
||||
private LmsAPITemplate createLmsSetupTemplate(final APITemplateDataSupplier apiTemplateDataSupplier) {
|
||||
private Result<LmsAPITemplate> createLmsSetupTemplate(final APITemplateDataSupplier apiTemplateDataSupplier) {
|
||||
|
||||
final LmsType lmsType = apiTemplateDataSupplier.getLmsSetup().lmsType;
|
||||
|
||||
|
@ -268,8 +239,7 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
.get(lmsType);
|
||||
|
||||
return lmsAPITemplateFactory
|
||||
.create(apiTemplateDataSupplier)
|
||||
.getOrThrow();
|
||||
.create(apiTemplateDataSupplier);
|
||||
}
|
||||
|
||||
/** Used to always get the actual LMS connection data from persistent */
|
||||
|
|
|
@ -1,313 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleUtils.MoodleQuizRestriction;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseAccess;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseRestriction;
|
||||
|
||||
@Deprecated
|
||||
public class MockupRestTemplateFactory implements MoodleRestTemplateFactory {
|
||||
|
||||
private final APITemplateDataSupplier apiTemplateDataSupplier;
|
||||
|
||||
public MockupRestTemplateFactory(final APITemplateDataSupplier apiTemplateDataSupplier) {
|
||||
this.apiTemplateDataSupplier = apiTemplateDataSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LmsSetupTestResult test() {
|
||||
return LmsSetupTestResult.ofOkay(LmsType.MOODLE_PLUGIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public APITemplateDataSupplier getApiTemplateDataSupplier() {
|
||||
return this.apiTemplateDataSupplier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getKnownTokenAccessPaths() {
|
||||
final Set<String> paths = new HashSet<>();
|
||||
paths.add(MoodleAPIRestTemplate.MOODLE_DEFAULT_TOKEN_REQUEST_PATH);
|
||||
return paths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate() {
|
||||
return Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String accessTokenPath) {
|
||||
return Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
||||
}
|
||||
|
||||
public static final class MockupMoodleRestTemplate implements MoodleAPIRestTemplate {
|
||||
|
||||
private final String accessToken = UUID.randomUUID().toString();
|
||||
private final String url;
|
||||
|
||||
public MockupMoodleRestTemplate(final String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getService() {
|
||||
return "mockup-service";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setService(final String service) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getAccessToken() {
|
||||
System.out.println("***** getAccessToken: " + this.accessToken);
|
||||
return this.accessToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testAPIConnection(final String... functions) {
|
||||
System.out.println("***** testAPIConnection functions: " + functions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String callMoodleAPIFunction(final String functionName) {
|
||||
return callMoodleAPIFunction(functionName, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String callMoodleAPIFunction(
|
||||
final String functionName,
|
||||
final MultiValueMap<String, String> queryAttributes) {
|
||||
return callMoodleAPIFunction(functionName, null, queryAttributes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String callMoodleAPIFunction(
|
||||
final String functionName,
|
||||
final MultiValueMap<String, String> queryParams,
|
||||
final MultiValueMap<String, String> queryAttributes) {
|
||||
|
||||
final UriComponentsBuilder queryParam = UriComponentsBuilder
|
||||
.fromHttpUrl(this.url + MOODLE_DEFAULT_REST_API_PATH)
|
||||
.queryParam(REST_REQUEST_TOKEN_NAME, this.accessToken)
|
||||
.queryParam(REST_REQUEST_FUNCTION_NAME, functionName)
|
||||
.queryParam(REST_REQUEST_FORMAT_NAME, "json");
|
||||
|
||||
if (queryParams != null && !queryParams.isEmpty()) {
|
||||
queryParam.queryParams(queryParams);
|
||||
}
|
||||
|
||||
final boolean usePOST = queryAttributes != null && !queryAttributes.isEmpty();
|
||||
HttpEntity<?> functionReqEntity;
|
||||
if (usePOST) {
|
||||
final HttpHeaders headers = new HttpHeaders();
|
||||
headers.set(
|
||||
HttpHeaders.CONTENT_TYPE,
|
||||
MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
|
||||
final String body = Utils.toAppFormUrlEncodedBody(queryAttributes);
|
||||
functionReqEntity = new HttpEntity<>(body, headers);
|
||||
|
||||
} else {
|
||||
functionReqEntity = new HttpEntity<>(new LinkedMultiValueMap<>());
|
||||
}
|
||||
|
||||
System.out.println("***** callMoodleAPIFunction HttpEntity: " + functionReqEntity);
|
||||
|
||||
if (MoodlePluginCourseAccess.COURSES_API_FUNCTION_NAME.equals(functionName)) {
|
||||
return respondCourses(queryAttributes);
|
||||
} else if (MoodlePluginCourseAccess.USERS_API_FUNCTION_NAME.equals(functionName)) {
|
||||
return respondUsers(queryAttributes);
|
||||
} else if (MoodlePluginCourseRestriction.RESTRICTION_GET_FUNCTION_NAME.equals(functionName)) {
|
||||
|
||||
return respondGetRestriction(
|
||||
queryParams.getFirst(MoodlePluginCourseRestriction.ATTRIBUTE_QUIZ_ID),
|
||||
queryAttributes);
|
||||
} else if (MoodlePluginCourseRestriction.RESTRICTION_SET_FUNCTION_NAME.equals(functionName)) {
|
||||
return respondSetRestriction(
|
||||
queryParams.getFirst(MoodlePluginCourseRestriction.ATTRIBUTE_QUIZ_ID),
|
||||
queryAttributes);
|
||||
}
|
||||
|
||||
else {
|
||||
throw new RuntimeException("Unknown function: " + functionName);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final class MockCD {
|
||||
public final String id;
|
||||
public final String shortname;
|
||||
public final String categoryid;
|
||||
public final String fullname;
|
||||
public final String displayname;
|
||||
public final String idnumber;
|
||||
public final Long startdate; // unix-time seconds UTC
|
||||
public final Long enddate; // unix-time seconds UTC
|
||||
public final Long timecreated; // unix-time seconds UTC
|
||||
public final boolean visible;
|
||||
public final Collection<MockQ> quizzes;
|
||||
|
||||
public MockCD(final String num, final Collection<MockQ> quizzes) {
|
||||
this.id = num;
|
||||
this.shortname = "c" + num;
|
||||
this.categoryid = "mock";
|
||||
this.fullname = "course" + num;
|
||||
this.displayname = this.fullname;
|
||||
this.idnumber = "i" + num;
|
||||
this.startdate = Long.valueOf(num);
|
||||
this.enddate = null;
|
||||
this.timecreated = Long.valueOf(num);
|
||||
this.visible = true;
|
||||
this.quizzes = quizzes;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final class MockQ {
|
||||
public final String id;
|
||||
public final String coursemodule;
|
||||
public final String course;
|
||||
public final String name;
|
||||
public final String intro;
|
||||
public final Long timeopen; // unix-time seconds UTC
|
||||
public final Long timeclose; // unix-time seconds UTC
|
||||
|
||||
public MockQ(final String courseId, final String num) {
|
||||
this.id = num;
|
||||
this.coursemodule = courseId;
|
||||
this.course = courseId;
|
||||
this.name = "quiz " + num;
|
||||
this.intro = this.name;
|
||||
this.timeopen = Long.valueOf(num);
|
||||
this.timeclose = null;
|
||||
}
|
||||
}
|
||||
|
||||
private String respondCourses(final MultiValueMap<String, String> queryAttributes) {
|
||||
try {
|
||||
final List<String> ids = queryAttributes.get(MoodlePluginCourseAccess.PARAM_COURSE_ID);
|
||||
final String from = queryAttributes.getFirst(MoodlePluginCourseAccess.PARAM_PAGE_START);
|
||||
System.out.println("************* from: " + from);
|
||||
final List<MockCD> courses;
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
courses = ids
|
||||
.stream()
|
||||
.map(id -> new MockCD(
|
||||
id,
|
||||
getQuizzesForCourse(Integer.parseInt(id))))
|
||||
.collect(Collectors.toList());
|
||||
} else if (from != null && Integer.valueOf(from) < 11) {
|
||||
courses = new ArrayList<>();
|
||||
final int num = (Integer.valueOf(from) > 0) ? 10 : 1;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
courses.add(new MockCD(String.valueOf(num + i), getQuizzesForCourse(num + i)));
|
||||
}
|
||||
} else {
|
||||
courses = new ArrayList<>();
|
||||
}
|
||||
|
||||
final Map<String, Object> response = new HashMap<>();
|
||||
response.put("results", courses);
|
||||
final JSONMapper jsonMapper = new JSONMapper();
|
||||
final String result = jsonMapper.writeValueAsString(response);
|
||||
System.out.println("******** courses response: " + result);
|
||||
return result;
|
||||
} catch (final JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<String, MoodleQuizRestriction> restrcitions = new HashMap<>();
|
||||
|
||||
private String respondSetRestriction(final String quizId, final MultiValueMap<String, String> queryAttributes) {
|
||||
final List<String> configKeys = queryAttributes.get(MoodlePluginCourseRestriction.ATTRIBUTE_CONFIG_KEYS);
|
||||
final List<String> beks = queryAttributes.get(MoodlePluginCourseRestriction.ATTRIBUTE_BROWSER_EXAM_KEYS);
|
||||
final String quitURL = queryAttributes.getFirst(MoodlePluginCourseRestriction.ATTRIBUTE_QUIT_URL);
|
||||
final String quitSecret = queryAttributes.getFirst(MoodlePluginCourseRestriction.ATTRIBUTE_QUIT_SECRET);
|
||||
|
||||
final MoodleQuizRestriction moodleQuizRestriction = new MoodleQuizRestriction(
|
||||
quizId,
|
||||
StringUtils.join(configKeys, Constants.LIST_SEPARATOR),
|
||||
StringUtils.join(beks, Constants.LIST_SEPARATOR),
|
||||
quitURL,
|
||||
quitSecret);
|
||||
this.restrcitions.put(quizId, moodleQuizRestriction);
|
||||
|
||||
final JSONMapper jsonMapper = new JSONMapper();
|
||||
try {
|
||||
return jsonMapper.writeValueAsString(moodleQuizRestriction);
|
||||
} catch (final JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String respondGetRestriction(final String quizId, final MultiValueMap<String, String> queryAttributes) {
|
||||
final MoodleQuizRestriction moodleQuizRestriction = this.restrcitions.get(quizId);
|
||||
if (moodleQuizRestriction != null) {
|
||||
final JSONMapper jsonMapper = new JSONMapper();
|
||||
try {
|
||||
return jsonMapper.writeValueAsString(moodleQuizRestriction);
|
||||
} catch (final JsonProcessingException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private Collection<MockQ> getQuizzesForCourse(final int courseId) {
|
||||
final String id = String.valueOf(courseId);
|
||||
final Collection<MockQ> result = new ArrayList<>();
|
||||
result.add(new MockQ(id, "10" + id));
|
||||
if (courseId % 2 > 0) {
|
||||
result.add(new MockQ(id, "11" + id));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String respondUsers(final MultiValueMap<String, String> queryAttributes) {
|
||||
// TODO
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
@ -25,52 +24,39 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
|||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.LmsAPITemplateAdapter;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodlePluginCheck;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactoryImpl;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseAccess;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseRestriction;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
@WebServiceProfile
|
||||
public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
|
||||
|
||||
private final MoodlePluginCheck moodlePluginCheck;
|
||||
private final JSONMapper jsonMapper;
|
||||
private final CacheManager cacheManager;
|
||||
private final AsyncService asyncService;
|
||||
private final Environment environment;
|
||||
private final ClientCredentialService clientCredentialService;
|
||||
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
|
||||
private final ExamConfigurationValueService examConfigurationValueService;
|
||||
private final ApplicationContext applicationContext;
|
||||
private final String[] alternativeTokenRequestPaths;
|
||||
|
||||
protected MoodleLmsAPITemplateFactory(
|
||||
final MoodlePluginCheck moodlePluginCheck,
|
||||
final JSONMapper jsonMapper,
|
||||
final CacheManager cacheManager,
|
||||
final AsyncService asyncService,
|
||||
final Environment environment,
|
||||
final ClientCredentialService clientCredentialService,
|
||||
final ExamConfigurationValueService examConfigurationValueService,
|
||||
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
|
||||
final ApplicationContext applicationContext,
|
||||
@Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths) {
|
||||
|
||||
this.moodlePluginCheck = moodlePluginCheck;
|
||||
this.jsonMapper = jsonMapper;
|
||||
this.cacheManager = cacheManager;
|
||||
this.asyncService = asyncService;
|
||||
this.environment = environment;
|
||||
this.clientCredentialService = clientCredentialService;
|
||||
this.examConfigurationValueService = examConfigurationValueService;
|
||||
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
|
||||
this.applicationContext = applicationContext;
|
||||
this.alternativeTokenRequestPaths = (alternativeTokenRequestPaths != null)
|
||||
|
@ -100,43 +86,20 @@ public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
|
|||
this.clientHttpRequestFactoryService,
|
||||
this.alternativeTokenRequestPaths);
|
||||
|
||||
if (this.moodlePluginCheck.checkPluginAvailable(restTemplateFactory)) {
|
||||
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
||||
this.jsonMapper,
|
||||
this.asyncService,
|
||||
restTemplateFactory,
|
||||
asyncLoaderPrototype,
|
||||
this.environment);
|
||||
|
||||
final MoodlePluginCourseAccess moodlePluginCourseAccess = new MoodlePluginCourseAccess(
|
||||
this.jsonMapper,
|
||||
this.asyncService,
|
||||
restTemplateFactory,
|
||||
this.cacheManager,
|
||||
this.environment);
|
||||
return new LmsAPITemplateAdapter(
|
||||
this.asyncService,
|
||||
this.environment,
|
||||
apiTemplateDataSupplier,
|
||||
moodleCourseAccess,
|
||||
new MoodleCourseRestriction());
|
||||
|
||||
final MoodlePluginCourseRestriction moodlePluginCourseRestriction = new MoodlePluginCourseRestriction(
|
||||
this.jsonMapper,
|
||||
restTemplateFactory,
|
||||
this.examConfigurationValueService);
|
||||
|
||||
return new LmsAPITemplateAdapter(
|
||||
this.asyncService,
|
||||
this.environment,
|
||||
apiTemplateDataSupplier,
|
||||
moodlePluginCourseAccess,
|
||||
moodlePluginCourseRestriction);
|
||||
|
||||
} else {
|
||||
|
||||
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
||||
this.jsonMapper,
|
||||
this.asyncService,
|
||||
restTemplateFactory,
|
||||
asyncLoaderPrototype,
|
||||
this.environment);
|
||||
|
||||
return new LmsAPITemplateAdapter(
|
||||
this.asyncService,
|
||||
this.environment,
|
||||
apiTemplateDataSupplier,
|
||||
moodleCourseAccess,
|
||||
new MoodleCourseRestriction());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,6 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
|
|||
USERS_API_FUNCTION_NAME);
|
||||
|
||||
} catch (final RuntimeException e) {
|
||||
log.error("Failed to access Moodle course API: ", e);
|
||||
return LmsSetupTestResult.ofQuizAccessAPIError(LmsType.MOODLE_PLUGIN, e.getMessage());
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -29,9 +28,9 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.LmsAPITemplateAdapter;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MockupRestTemplateFactory;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodlePluginCheck;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactoryImpl;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
|
@ -46,7 +45,6 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
|
|||
private final ClientCredentialService clientCredentialService;
|
||||
private final ExamConfigurationValueService examConfigurationValueService;
|
||||
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
|
||||
private final ApplicationContext applicationContext;
|
||||
private final String[] alternativeTokenRequestPaths;
|
||||
|
||||
protected MooldePluginLmsAPITemplateFactory(
|
||||
|
@ -58,7 +56,6 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
|
|||
final ClientCredentialService clientCredentialService,
|
||||
final ExamConfigurationValueService examConfigurationValueService,
|
||||
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
|
||||
final ApplicationContext applicationContext,
|
||||
@Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths) {
|
||||
|
||||
this.moodlePluginCheck = moodlePluginCheck;
|
||||
|
@ -69,7 +66,6 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
|
|||
this.clientCredentialService = clientCredentialService;
|
||||
this.examConfigurationValueService = examConfigurationValueService;
|
||||
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
|
||||
this.applicationContext = applicationContext;
|
||||
this.alternativeTokenRequestPaths = (alternativeTokenRequestPaths != null)
|
||||
? StringUtils.split(alternativeTokenRequestPaths, Constants.LIST_SEPARATOR)
|
||||
: null;
|
||||
|
@ -84,15 +80,16 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
|
|||
public Result<LmsAPITemplate> create(final APITemplateDataSupplier apiTemplateDataSupplier) {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
// final MoodleRestTemplateFactory moodleRestTemplateFactory = new MoodleRestTemplateFactoryImpl(
|
||||
// this.jsonMapper,
|
||||
// apiTemplateDataSupplier,
|
||||
// this.clientCredentialService,
|
||||
// this.clientHttpRequestFactoryService,
|
||||
// this.alternativeTokenRequestPaths);
|
||||
final MoodleRestTemplateFactory moodleRestTemplateFactory = new MoodleRestTemplateFactoryImpl(
|
||||
this.jsonMapper,
|
||||
apiTemplateDataSupplier,
|
||||
this.clientCredentialService,
|
||||
this.clientHttpRequestFactoryService,
|
||||
this.alternativeTokenRequestPaths);
|
||||
|
||||
final MoodleRestTemplateFactory moodleRestTemplateFactory =
|
||||
new MockupRestTemplateFactory(apiTemplateDataSupplier);
|
||||
// if (!this.moodlePluginCheck.checkPluginAvailable(moodleRestTemplateFactory)) {
|
||||
// throw new RuntimeException("Unable to detect SEB Server Moodle integration plugin!");
|
||||
// }
|
||||
|
||||
final MoodlePluginCourseAccess moodlePluginCourseAccess = new MoodlePluginCourseAccess(
|
||||
this.jsonMapper,
|
||||
|
|
|
@ -28,7 +28,9 @@ import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult.ErrorType;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordDynamicSqlSupport;
|
||||
|
@ -93,9 +95,16 @@ public class LmsSetupController extends ActivatableEntityController<LmsSetup, Lm
|
|||
EntityType.LMS_SETUP,
|
||||
institutionId);
|
||||
|
||||
final LmsSetupTestResult result = this.lmsAPIService.getLmsAPITemplate(modelId)
|
||||
final LmsSetupTestResult result = this.lmsAPIService
|
||||
.getLmsAPITemplate(modelId)
|
||||
.map(this.lmsAPIService::test)
|
||||
.getOrThrow();
|
||||
.onErrorDo(error -> {
|
||||
final LmsType lmsType = this.entityDAO.byPK(modelId).get().lmsType;
|
||||
return new LmsSetupTestResult(
|
||||
lmsType,
|
||||
new LmsSetupTestResult.Error(ErrorType.TEMPLATE_CREATION, error.getMessage()));
|
||||
})
|
||||
.get();
|
||||
|
||||
if (result.missingLMSSetupAttribute != null && !result.missingLMSSetupAttribute.isEmpty()) {
|
||||
throw new APIMessageException(result.missingLMSSetupAttribute);
|
||||
|
|
|
@ -328,6 +328,8 @@ sebserver.useraccount.delete.confirm.message.noDeps=The User Account ({0}) was s
|
|||
|
||||
sebserver.lmssetup.type.MOCKUP=Testing
|
||||
sebserver.lmssetup.type.MOODLE=Moodle
|
||||
sebserver.lmssetup.type.MOODLE_PLUGIN=Moodle Plugin
|
||||
sebserver.lmssetup.type.MOODLE_PLUGIN.tooltip=Moodle with SEB Server integration plugin installed
|
||||
sebserver.lmssetup.type.OPEN_EDX=Open edX
|
||||
sebserver.lmssetup.type.ANS_DELFT=Ans Delft
|
||||
sebserver.lmssetup.type.OPEN_OLAT=Open OLAT
|
||||
|
@ -365,6 +367,7 @@ sebserver.lmssetup.action.test.quizRestrictionError=Unable to access course rest
|
|||
sebserver.lmssetup.action.test.features.error=The API access was granted but there is some missing functionality:<br/><br/>- Course Access: {0}<br/>- SEB Restriction: {1}
|
||||
sebserver.lmssetup.action.test.missingParameter=There is one or more missing connection parameter.<br/>Please check the connection parameter for this LMS Setup
|
||||
sebserver.lmssetup.action.test.unknownError=An unexpected error happened while trying to connect to the LMS course API. {0}
|
||||
sebserver.lmssetup.action.test.quizRequestError.moodle.missing.plugin=Moodle SEB Server integration plugin cannot be detected on this Moodle server.<br/>Please consider using the origin "Moodle" LMS Setup type or install the SEB Server integration plugin on this Moodle server.<br/><br/>For further information please refer to the <a target="_blank" href="https://seb-server.readthedocs.io/en/latest/#">documentation</a>
|
||||
sebserver.lmssetup.action.save=Save LMS Setup
|
||||
sebserver.lmssetup.action.activate=Activate LMS Setup
|
||||
sebserver.lmssetup.action.deactivate=Deactivate LMS Setup
|
||||
|
|
Loading…
Reference in a new issue