SEBSERV-30 preparing for Exam and Quiz gui and javadoc
This commit is contained in:
parent
7b2f7228af
commit
d404498475
35 changed files with 877 additions and 196 deletions
|
@ -48,7 +48,7 @@ public final class API {
|
|||
|
||||
public static final String USER_ACCOUNT_ENDPOINT = "/useraccount";
|
||||
|
||||
public static final String QUIZ_IMPORT_ENDPOINT = "/quiz";
|
||||
public static final String QUIZ_DISCOVERY_ENDPOINT = "/quiz";
|
||||
|
||||
public static final String EXAM_ADMINISTRATION_ENDPOINT = "/exam";
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ public final class QuizData implements Entity {
|
|||
public static final String FILTER_ATTR_START_TIME = "start_timestamp";
|
||||
|
||||
public static final String QUIZ_ATTR_ID = "quiz_id";
|
||||
public static final String QUIZ_ATTR_LMS_SETUP_ID = "lms_setup_id";
|
||||
public static final String QUIZ_ATTR_NAME = "quiz_name";
|
||||
public static final String QUIZ_ATTR_DESCRIPTION = "quiz_description";
|
||||
public static final String QUIZ_ATTR_START_TIME = "quiz_start_time";
|
||||
|
@ -36,6 +37,9 @@ public final class QuizData implements Entity {
|
|||
@JsonProperty(QUIZ_ATTR_ID)
|
||||
public final String id;
|
||||
|
||||
@JsonProperty(QUIZ_ATTR_LMS_SETUP_ID)
|
||||
public final String lmsSetupId;
|
||||
|
||||
@JsonProperty(QUIZ_ATTR_NAME)
|
||||
public final String name;
|
||||
|
||||
|
@ -54,6 +58,7 @@ public final class QuizData implements Entity {
|
|||
@JsonCreator
|
||||
public QuizData(
|
||||
@JsonProperty(QUIZ_ATTR_ID) final String id,
|
||||
@JsonProperty(QUIZ_ATTR_LMS_SETUP_ID) final String lmsSetupId,
|
||||
@JsonProperty(QUIZ_ATTR_NAME) final String name,
|
||||
@JsonProperty(QUIZ_ATTR_DESCRIPTION) final String description,
|
||||
@JsonProperty(QUIZ_ATTR_START_TIME) final DateTime startTime,
|
||||
|
@ -61,6 +66,7 @@ public final class QuizData implements Entity {
|
|||
@JsonProperty(QUIZ_ATTR_START_URL) final String startURL) {
|
||||
|
||||
this.id = id;
|
||||
this.lmsSetupId = lmsSetupId;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.startTime = startTime;
|
||||
|
@ -70,6 +76,7 @@ public final class QuizData implements Entity {
|
|||
|
||||
public QuizData(
|
||||
final String id,
|
||||
final String lmsSetupId,
|
||||
final String name,
|
||||
final String description,
|
||||
final String startTime,
|
||||
|
@ -77,6 +84,7 @@ public final class QuizData implements Entity {
|
|||
final String startURL) {
|
||||
|
||||
this.id = id;
|
||||
this.lmsSetupId = lmsSetupId;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.startTime = LocalDateTime
|
||||
|
@ -106,6 +114,10 @@ public final class QuizData implements Entity {
|
|||
return this.id;
|
||||
}
|
||||
|
||||
public String getLmsSetupId() {
|
||||
return this.lmsSetupId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
|
@ -154,9 +166,9 @@ public final class QuizData implements Entity {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "QuizData [id=" + this.id + ", name=" + this.name + ", description=" + this.description + ", startTime="
|
||||
+ this.startTime
|
||||
+ ", endTime=" + this.endTime + ", startURL=" + this.startURL + "]";
|
||||
return "QuizData [id=" + this.id + ", lmsSetupId=" + this.lmsSetupId + ", name=" + this.name + ", description="
|
||||
+ this.description
|
||||
+ ", startTime=" + this.startTime + ", endTime=" + this.endTime + ", startURL=" + this.startURL + "]";
|
||||
}
|
||||
|
||||
public static Comparator<QuizData> getIdComparator(final boolean descending) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.content;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.form.PageFormService;
|
||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class ExamForm implements TemplateComposer {
|
||||
|
||||
private final PageFormService pageFormService;
|
||||
private final ResourceService resourceService;
|
||||
|
||||
protected ExamForm(
|
||||
final PageFormService pageFormService,
|
||||
final ResourceService resourceService) {
|
||||
|
||||
this.pageFormService = pageFormService;
|
||||
this.resourceService = resourceService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compose(final PageContext pageContext) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.content;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class ExamList implements TemplateComposer {
|
||||
|
||||
private final WidgetFactory widgetFactory;
|
||||
private final ResourceService resourceService;
|
||||
private final int pageSize;
|
||||
|
||||
protected ExamList(
|
||||
final WidgetFactory widgetFactory,
|
||||
final ResourceService resourceService,
|
||||
@Value("${sebserver.gui.list.page.size}") final Integer pageSize) {
|
||||
|
||||
this.widgetFactory = widgetFactory;
|
||||
this.resourceService = resourceService;
|
||||
this.pageSize = (pageSize != null) ? pageSize : 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compose(final PageContext pageContext) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -114,7 +114,7 @@ public class LmsSetupForm implements TemplateComposer {
|
|||
final EntityGrantCheck userGrantCheck = currentUser.entityGrantCheck(lmsSetup);
|
||||
final boolean writeGrant = userGrantCheck.w();
|
||||
final boolean modifyGrant = userGrantCheck.m();
|
||||
final boolean istitutionActive = restService.getBuilder(GetInstitution.class)
|
||||
final boolean institutionActive = restService.getBuilder(GetInstitution.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(lmsSetup.getInstitutionId()))
|
||||
.call()
|
||||
.map(inst -> inst.active)
|
||||
|
@ -177,27 +177,27 @@ public class LmsSetupForm implements TemplateComposer {
|
|||
formContext.clearEntityKeys()
|
||||
|
||||
.createAction(ActionDefinition.LMS_SETUP_NEW)
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive)
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive)
|
||||
|
||||
.createAction(ActionDefinition.LMS_SETUP_MODIFY)
|
||||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && readonly && istitutionActive)
|
||||
.publishIf(() -> modifyGrant && readonly && institutionActive)
|
||||
|
||||
.createAction(ActionDefinition.LMS_SETUP_TEST)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(action -> this.testLmsSetup(action, formHandle))
|
||||
.publishIf(() -> modifyGrant && isNotNew.getAsBoolean() && istitutionActive)
|
||||
.publishIf(() -> modifyGrant && isNotNew.getAsBoolean() && institutionActive)
|
||||
|
||||
.createAction(ActionDefinition.LMS_SETUP_DEACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(restService::activation)
|
||||
.withConfirm(PageUtils.confirmDeactivation(lmsSetup, restService))
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive && lmsSetup.isActive())
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive && lmsSetup.isActive())
|
||||
|
||||
.createAction(ActionDefinition.LMS_SETUP_ACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(restService::activation)
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive && !lmsSetup.isActive())
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive && !lmsSetup.isActive())
|
||||
|
||||
.createAction(ActionDefinition.LMS_SETUP_SAVE)
|
||||
.withExec(formHandle::processFormSave)
|
||||
|
@ -208,7 +208,6 @@ public class LmsSetupForm implements TemplateComposer {
|
|||
.withExec(Action::onEmptyEntityKeyGoToActivityHome)
|
||||
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
|
||||
.publishIf(() -> !readonly);
|
||||
|
||||
}
|
||||
|
||||
/** LmsSetup test action implementation */
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.content;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.ResourceService;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class QuizDiscoveryList implements TemplateComposer {
|
||||
|
||||
private final WidgetFactory widgetFactory;
|
||||
private final ResourceService resourceService;
|
||||
private final int pageSize;
|
||||
|
||||
protected QuizDiscoveryList(
|
||||
final WidgetFactory widgetFactory,
|
||||
final ResourceService resourceService,
|
||||
@Value("${sebserver.gui.list.page.size}") final Integer pageSize) {
|
||||
|
||||
this.widgetFactory = widgetFactory;
|
||||
this.resourceService = resourceService;
|
||||
this.pageSize = (pageSize != null) ? pageSize : 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compose(final PageContext pageContext) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -106,7 +106,7 @@ public class UserAccountForm implements TemplateComposer {
|
|||
final EntityGrantCheck userGrantCheck = currentUser.entityGrantCheck(userAccount);
|
||||
final boolean writeGrant = userGrantCheck.w();
|
||||
final boolean modifyGrant = userGrantCheck.m();
|
||||
final boolean istitutionActive = restService.getBuilder(GetInstitution.class)
|
||||
final boolean institutionActive = restService.getBuilder(GetInstitution.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(userAccount.getInstitutionId()))
|
||||
.call()
|
||||
.map(inst -> inst.active)
|
||||
|
@ -190,26 +190,26 @@ public class UserAccountForm implements TemplateComposer {
|
|||
formContext.clearEntityKeys()
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_NEW)
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive)
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_MODIFY)
|
||||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && readonly && istitutionActive)
|
||||
.publishIf(() -> modifyGrant && readonly && institutionActive)
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_CHANGE_PASSOWRD)
|
||||
.withEntityKey(entityKey)
|
||||
.publishIf(() -> modifyGrant && readonly && istitutionActive && userAccount.isActive())
|
||||
.publishIf(() -> modifyGrant && readonly && institutionActive && userAccount.isActive())
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_DEACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(restService::activation)
|
||||
.withConfirm(PageUtils.confirmDeactivation(userAccount, restService))
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive && userAccount.isActive())
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive && userAccount.isActive())
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_ACTIVATE)
|
||||
.withEntityKey(entityKey)
|
||||
.withExec(restService::activation)
|
||||
.publishIf(() -> writeGrant && readonly && istitutionActive && !userAccount.isActive())
|
||||
.publishIf(() -> writeGrant && readonly && institutionActive && !userAccount.isActive())
|
||||
|
||||
.createAction(ActionDefinition.USER_ACCOUNT_SAVE)
|
||||
.withExec(action -> {
|
||||
|
|
|
@ -216,6 +216,7 @@ public final class Form implements FormBinding {
|
|||
}
|
||||
}
|
||||
|
||||
// following are FormFieldAccessor implementations for all field types
|
||||
//@formatter:off
|
||||
private FormFieldAccessor createAccessor(final Label label, final Label field) {
|
||||
return new FormFieldAccessor(label, field) {
|
||||
|
@ -229,24 +230,17 @@ public final class Form implements FormBinding {
|
|||
@Override public void setValue(final String value) { text.setText(value); }
|
||||
};
|
||||
}
|
||||
private FormFieldAccessor createAccessor(
|
||||
final Label label,
|
||||
final SingleSelection singleSelection) {
|
||||
|
||||
private FormFieldAccessor createAccessor(final Label label, final SingleSelection singleSelection) {
|
||||
return new FormFieldAccessor(label, singleSelection) {
|
||||
@Override public String getValue() { return singleSelection.getSelectionValue(); }
|
||||
@Override public void setValue(final String value) { singleSelection.select(value); }
|
||||
};
|
||||
}
|
||||
private FormFieldAccessor createAccessor(
|
||||
final Label label,
|
||||
final MultiSelection multiSelection) {
|
||||
|
||||
private FormFieldAccessor createAccessor(final Label label,final MultiSelection multiSelection) {
|
||||
return new FormFieldAccessor(label, multiSelection) {
|
||||
@Override public String getValue() { return multiSelection.getSelectionValue(); }
|
||||
@Override public void setValue(final String value) { multiSelection.select(value); }
|
||||
@Override
|
||||
public void putJsonValue(final String key, final ObjectNode objectRoot) {
|
||||
@Override public void putJsonValue(final String key, final ObjectNode objectRoot) {
|
||||
final String value = getValue();
|
||||
if (StringUtils.isNoneBlank(value)) {
|
||||
final ArrayNode arrayNode = objectRoot.putArray(key);
|
||||
|
|
|
@ -31,6 +31,7 @@ import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
|||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionNames;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetupNames;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
|
||||
@Lazy
|
||||
|
@ -115,6 +116,35 @@ public class ResourceService {
|
|||
};
|
||||
}
|
||||
|
||||
public List<Tuple<String>> lmsSetupResource(final Long institutionId) {
|
||||
return this.restService.getBuilder(GetLmsSetupNames.class)
|
||||
.withQueryParam(Domain.LMS_SETUP.ATTR_INSTITUTION_ID, String.valueOf(institutionId))
|
||||
.withQueryParam(Domain.LMS_SETUP.ATTR_ACTIVE, "true")
|
||||
.call()
|
||||
.getOr(Collections.emptyList())
|
||||
.stream()
|
||||
.map(entityName -> new Tuple<>(entityName.modelId, entityName.name))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Function<String, String> getLmsSetupNameFunction(final Long institutionId) {
|
||||
|
||||
final Map<String, String> idNameMap = this.restService.getBuilder(GetLmsSetupNames.class)
|
||||
.withQueryParam(Domain.LMS_SETUP.ATTR_INSTITUTION_ID, String.valueOf(institutionId))
|
||||
.withQueryParam(Domain.INSTITUTION.ATTR_ACTIVE, "true")
|
||||
.call()
|
||||
.getOr(Collections.emptyList())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(e -> e.modelId, e -> e.name));
|
||||
|
||||
return id -> {
|
||||
if (!idNameMap.containsKey(id)) {
|
||||
return Constants.EMPTY_NOTE;
|
||||
}
|
||||
return idNameMap.get(id);
|
||||
};
|
||||
}
|
||||
|
||||
/** Get a list of language key/name tuples for all supported languages in the
|
||||
* language of the current users locale.
|
||||
*
|
||||
|
|
|
@ -16,6 +16,10 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/** Puts RAP's server-push functionality in a well defined service by using a context
|
||||
* as state holder and the possibility to split the server-push process into two
|
||||
* separated processes, a business-process to get and update business data and the
|
||||
* an update-process to update the UI after according to updated data */
|
||||
@Lazy
|
||||
@Service
|
||||
public class ServerPushService {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -25,8 +26,10 @@ import org.springframework.util.LinkedMultiValueMap;
|
|||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestClientResponseException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
|
@ -100,20 +103,7 @@ public abstract class RestCall<T> {
|
|||
RestCall.this.typeKey.typeRef));
|
||||
|
||||
} else {
|
||||
|
||||
final RestCallError restCallError =
|
||||
new RestCallError("Response Entity: " + responseEntity.toString());
|
||||
|
||||
restCallError.errors.addAll(RestCall.this.jsonMapper.readValue(
|
||||
responseEntity.getBody(),
|
||||
new TypeReference<List<APIMessage>>() {
|
||||
}));
|
||||
|
||||
log.debug(
|
||||
"Webservice answered with well defined error- or validation-failure-response: ",
|
||||
restCallError);
|
||||
|
||||
return Result.ofError(restCallError);
|
||||
return handleRestCallError(responseEntity);
|
||||
}
|
||||
|
||||
} catch (final Throwable t) {
|
||||
|
@ -149,6 +139,24 @@ public abstract class RestCall<T> {
|
|||
return new RestCallBuilder();
|
||||
}
|
||||
|
||||
private Result<T> handleRestCallError(final ResponseEntity<String> responseEntity)
|
||||
throws IOException, JsonParseException, JsonMappingException {
|
||||
|
||||
final RestCallError restCallError =
|
||||
new RestCallError("Response Entity: " + responseEntity.toString());
|
||||
|
||||
restCallError.errors.addAll(RestCall.this.jsonMapper.readValue(
|
||||
responseEntity.getBody(),
|
||||
new TypeReference<List<APIMessage>>() {
|
||||
}));
|
||||
|
||||
log.debug(
|
||||
"Webservice answered with well defined error- or validation-failure-response: ",
|
||||
restCallError);
|
||||
|
||||
return Result.ofError(restCallError);
|
||||
}
|
||||
|
||||
public class RestCallBuilder {
|
||||
|
||||
private final HttpHeaders httpHeaders = new HttpHeaders();
|
||||
|
|
|
@ -8,113 +8,75 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
@GuiProfile
|
||||
public class RestService {
|
||||
/** Interface to SEB Server webservice API thought RestCall's
|
||||
* or thought Spring's RestTemplate on lower level.
|
||||
*
|
||||
* A RestCall's can be used to call a specified SEB Server webservice API endpoint with given request parameter.
|
||||
* This service collects all the available RestCalls and map them by Class type or EntityType and CallType.
|
||||
*
|
||||
* For Example if one want to get a certain User-Account by API request on SEB Server webservice API:
|
||||
*
|
||||
* <pre>
|
||||
* UserInfo userInfo = RestService.getBuilder(GetUserAccount.class)
|
||||
* .withURIVariable(API.PARAM_MODEL_ID, user-account-id) adds an URI path variable
|
||||
* .withQueryParam(API.PARAM_INSTITUTION_ID, institutionId) adds a URI query parameter
|
||||
* .call() executes the API request call
|
||||
* .get(pageContext::notifyError) gets the result or notify an error to the user if happened
|
||||
* </pre>
|
||||
*/
|
||||
public interface RestService {
|
||||
|
||||
private final AuthorizationContextHolder authorizationContextHolder;
|
||||
private final WebserviceURIService webserviceURIBuilderSupplier;
|
||||
private final Map<String, RestCall<?>> calls;
|
||||
/** Get Spring's RestTemplate that is used within this service.
|
||||
*
|
||||
* @return Spring's RestTemplate that is used within this service. */
|
||||
RestTemplate getWebserviceAPIRestTemplate();
|
||||
|
||||
public RestService(
|
||||
final AuthorizationContextHolder authorizationContextHolder,
|
||||
final JSONMapper jsonMapper,
|
||||
final Collection<RestCall<?>> calls) {
|
||||
/** Get Spring's UriComponentsBuilder that is used within this service.
|
||||
*
|
||||
* @return Spring's UriComponentsBuilder that is used within this service. */
|
||||
UriComponentsBuilder getWebserviceURIBuilder();
|
||||
|
||||
this.authorizationContextHolder = authorizationContextHolder;
|
||||
this.webserviceURIBuilderSupplier = authorizationContextHolder
|
||||
.getWebserviceURIService();
|
||||
/** Get a certain RestCall by Class type.
|
||||
*
|
||||
* @param type the Class type of the RestCall
|
||||
* @return RestCall instance */
|
||||
<T> RestCall<T> getRestCall(Class<? extends RestCall<T>> type);
|
||||
|
||||
this.calls = calls
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
call -> call.getClass().getName(),
|
||||
call -> call.init(this, jsonMapper)));
|
||||
}
|
||||
/** Get a certain RestCall by EntityType and CallType.
|
||||
* NOTE not all RestCall can be get within this method. Only the ones that have a defined CallType
|
||||
*
|
||||
* @param entityType The EntityType of the RestCall
|
||||
* @param callType The CallType of the RestCall (not UNDEFINDED)
|
||||
* @return RestCall instance */
|
||||
<T> RestCall<T> getRestCall(EntityType entityType, CallType callType);
|
||||
|
||||
public final RestTemplate getWebserviceAPIRestTemplate() {
|
||||
return this.authorizationContextHolder
|
||||
.getAuthorizationContext()
|
||||
.getRestTemplate();
|
||||
}
|
||||
/** Get a certain RestCallBuilder by RestCall Class type.
|
||||
*
|
||||
* @param type the Class type of the RestCall
|
||||
* @return RestCallBuilder instance to build a dedicated call and execute it */
|
||||
<T> RestCall<T>.RestCallBuilder getBuilder(Class<? extends RestCall<T>> type);
|
||||
|
||||
public final UriComponentsBuilder getWebserviceURIBuilder() {
|
||||
return this.webserviceURIBuilderSupplier.getURIBuilder();
|
||||
}
|
||||
/** Get a certain RestCallBuilder by EntityType and CallType.
|
||||
*
|
||||
* @param entityType The EntityType of the RestCall to get a builder for
|
||||
* @param callType The CallType of the RestCall to get a builder for (not UNDEFINDED)
|
||||
* @return RestCallBuilder instance to build a dedicated call and execute it */
|
||||
<T> RestCall<T>.RestCallBuilder getBuilder(
|
||||
EntityType entityType,
|
||||
CallType callType);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <T> RestCall<T> getRestCall(final Class<? extends RestCall<T>> type) {
|
||||
return (RestCall<T>) this.calls.get(type.getName());
|
||||
}
|
||||
/** Performs an activation Action on RestCall specified within the given Action.
|
||||
* The RestCall must be of CallType.ACTIVATION_ACTIVATE or CallType.ACTIVATION_DEACTIVATE
|
||||
*
|
||||
* @param action the Action that defines an entity activation
|
||||
* @return the successfully executed Action */
|
||||
<T> Action activation(Action action);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <T> RestCall<T> getRestCall(final EntityType entityType, final CallType callType) {
|
||||
return (RestCall<T>) this.calls.values()
|
||||
.stream()
|
||||
.filter(call -> call.typeKey.callType == callType && call.typeKey.entityType == entityType)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public final <T> RestCall<T>.RestCallBuilder getBuilder(final Class<? extends RestCall<T>> type) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final RestCall<T> restCall = (RestCall<T>) this.calls.get(type.getName());
|
||||
if (restCall == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return restCall.newBuilder();
|
||||
}
|
||||
|
||||
public final <T> RestCall<T>.RestCallBuilder getBuilder(
|
||||
final EntityType entityType,
|
||||
final CallType callType) {
|
||||
|
||||
final RestCall<T> restCall = getRestCall(entityType, callType);
|
||||
if (restCall == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return restCall.newBuilder();
|
||||
}
|
||||
|
||||
public <T> Action activation(final Action action) {
|
||||
if (action.definition.restCallType == null) {
|
||||
throw new IllegalArgumentException("ActionDefinition needs to define a restCallType to use this action");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Class<? extends RestCall<T>> restCallType =
|
||||
(Class<? extends RestCall<T>>) action.definition.restCallType;
|
||||
|
||||
this.getBuilder(restCallType)
|
||||
.withURIVariable(
|
||||
API.PARAM_MODEL_ID,
|
||||
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
|
||||
.call()
|
||||
.onErrorDo(t -> action.pageContext().notifyError(t));
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.action.Action;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall.CallType;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
@GuiProfile
|
||||
public class RestServiceImpl implements RestService {
|
||||
|
||||
private final AuthorizationContextHolder authorizationContextHolder;
|
||||
private final WebserviceURIService webserviceURIBuilderSupplier;
|
||||
private final Map<String, RestCall<?>> calls;
|
||||
|
||||
public RestServiceImpl(
|
||||
final AuthorizationContextHolder authorizationContextHolder,
|
||||
final JSONMapper jsonMapper,
|
||||
final Collection<RestCall<?>> calls) {
|
||||
|
||||
this.authorizationContextHolder = authorizationContextHolder;
|
||||
this.webserviceURIBuilderSupplier = authorizationContextHolder
|
||||
.getWebserviceURIService();
|
||||
|
||||
this.calls = calls
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
call -> call.getClass().getName(),
|
||||
call -> call.init(this, jsonMapper)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RestTemplate getWebserviceAPIRestTemplate() {
|
||||
return this.authorizationContextHolder
|
||||
.getAuthorizationContext()
|
||||
.getRestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UriComponentsBuilder getWebserviceURIBuilder() {
|
||||
return this.webserviceURIBuilderSupplier.getURIBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <T> RestCall<T> getRestCall(final Class<? extends RestCall<T>> type) {
|
||||
return (RestCall<T>) this.calls.get(type.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final <T> RestCall<T> getRestCall(final EntityType entityType, final CallType callType) {
|
||||
|
||||
if (callType == CallType.UNDEFINED) {
|
||||
throw new IllegalArgumentException("Undefined CallType not supported");
|
||||
}
|
||||
|
||||
return (RestCall<T>) this.calls.values()
|
||||
.stream()
|
||||
.filter(call -> call.typeKey.callType == callType && call.typeKey.entityType == entityType)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> RestCall<T>.RestCallBuilder getBuilder(final Class<? extends RestCall<T>> type) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final RestCall<T> restCall = (RestCall<T>) this.calls.get(type.getName());
|
||||
if (restCall == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return restCall.newBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T> RestCall<T>.RestCallBuilder getBuilder(
|
||||
final EntityType entityType,
|
||||
final CallType callType) {
|
||||
|
||||
if (callType == CallType.UNDEFINED) {
|
||||
throw new IllegalArgumentException("Undefined CallType not supported");
|
||||
}
|
||||
|
||||
final RestCall<T> restCall = getRestCall(entityType, callType);
|
||||
if (restCall == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return restCall.newBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Action activation(final Action action) {
|
||||
if (action.definition.restCallType == null) {
|
||||
throw new IllegalArgumentException("ActionDefinition needs to define a restCallType to use this action");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final Class<? extends RestCall<T>> restCallType =
|
||||
(Class<? extends RestCall<T>>) action.definition.restCallType;
|
||||
|
||||
this.getBuilder(restCallType)
|
||||
.withURIVariable(
|
||||
API.PARAM_MODEL_ID,
|
||||
action.pageContext().getAttribute(AttributeKeys.ENTITY_ID))
|
||||
.call()
|
||||
.onErrorDo(t -> action.pageContext().notifyError(t));
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.exam;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class ActivateExam extends RestCall<EntityProcessingReport> {
|
||||
|
||||
protected ActivateExam() {
|
||||
super(new TypeKey<>(
|
||||
CallType.ACTIVATION_ACTIVATE,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<EntityProcessingReport>() {
|
||||
}),
|
||||
HttpMethod.POST,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT + API.PATH_VAR_ACTIVE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.exam;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class DeactivateExam extends RestCall<EntityProcessingReport> {
|
||||
|
||||
protected DeactivateExam() {
|
||||
super(new TypeKey<>(
|
||||
CallType.ACTIVATION_DEACTIVATE,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<EntityProcessingReport>() {
|
||||
}),
|
||||
HttpMethod.POST,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT + API.PATH_VAR_INACTIVE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.exam;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetExam extends RestCall<Exam> {
|
||||
|
||||
protected GetExam() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_SINGLE,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<Exam>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT + API.MODEL_ID_VAR_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.exam;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetExamDependencies extends RestCall<Set<EntityKey>> {
|
||||
|
||||
protected GetExamDependencies() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_DEPENDENCIES,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<Set<EntityKey>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT
|
||||
+ API.MODEL_ID_VAR_PATH_SEGMENT
|
||||
+ API.DEPENDENCY_PATH_SEGMENT);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.exam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityName;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetExamNames extends RestCall<List<EntityName>> {
|
||||
|
||||
protected GetExamNames() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_NAMES,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<List<EntityName>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT + API.NAMES_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.exam;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetExams extends RestCall<Page<Exam>> {
|
||||
|
||||
protected GetExams() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_PAGE,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<Page<Exam>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.exam;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class SaveExam extends RestCall<Exam> {
|
||||
|
||||
protected SaveExam() {
|
||||
super(new TypeKey<>(
|
||||
CallType.SAVE,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<Exam>() {
|
||||
}),
|
||||
HttpMethod.PUT,
|
||||
MediaType.APPLICATION_JSON_UTF8,
|
||||
API.EXAM_ADMINISTRATION_ENDPOINT);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.lmssetup;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityName;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetLmsSetupNames extends RestCall<List<EntityName>> {
|
||||
|
||||
protected GetLmsSetupNames() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_NAMES,
|
||||
EntityType.LMS_SETUP,
|
||||
new TypeReference<List<EntityName>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.LMS_SETUP_ENDPOINT + API.NAMES_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.quiz;
|
||||
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetQuizzes extends RestCall<Page<QuizData>> {
|
||||
|
||||
protected GetQuizzes() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_PAGE,
|
||||
EntityType.EXAM,
|
||||
new TypeReference<Page<QuizData>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.QUIZ_DISCOVERY_ENDPOINT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.gui.service.remote.webservice.api.quiz;
|
||||
|
||||
public class ImportAsExam {
|
||||
|
||||
}
|
|
@ -12,13 +12,28 @@ import javax.servlet.http.HttpSession;
|
|||
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
|
||||
/** Single point of access for SEBServerAuthorizationContext */
|
||||
public interface AuthorizationContextHolder {
|
||||
|
||||
/** Get the SEBServerAuthorizationContext that is bound the the given HttpSession.
|
||||
* If there is no AuthorizationContext or an invalid one within the given HttpSession
|
||||
* a new one is created for the given HttpSession
|
||||
*
|
||||
* @param session HttpSession instance
|
||||
* @return SEBServerAuthorizationContext instance */
|
||||
SEBServerAuthorizationContext getAuthorizationContext(HttpSession session);
|
||||
|
||||
/** Get the WebserviceURIService that is used within this AuthorizationContextHolder
|
||||
*
|
||||
* @return the WebserviceURIService that is used within this AuthorizationContextHolder */
|
||||
WebserviceURIService getWebserviceURIService();
|
||||
|
||||
// TODO error handling!?
|
||||
/** Get the SEBServerAuthorizationContext that is bound the HttpSession of the current
|
||||
* RWT UISession.
|
||||
* NOTE: This may throw an exception if RWT.getUISession().getHttpSession() throws one
|
||||
* This is the case if there is no RWT UISession within the current Thread
|
||||
*
|
||||
* @return SEBServerAuthorizationContext instance */
|
||||
default SEBServerAuthorizationContext getAuthorizationContext() {
|
||||
return getAuthorizationContext(RWT.getUISession().getHttpSession());
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP;
|
|||
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.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.client.ClientCredentials;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
|
@ -31,7 +30,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
|||
*
|
||||
* A LmsAPITemplate defines at least the core API access to query courses and quizzes from the LMS
|
||||
* Later a concrete LmsAPITemplate may also implement some special features regarding to the type
|
||||
* of LMS */
|
||||
* of the LMS */
|
||||
public interface LmsAPITemplate {
|
||||
|
||||
/** Get the underling LMSSetup configuration for this LmsAPITemplate
|
||||
|
@ -54,9 +53,17 @@ public interface LmsAPITemplate {
|
|||
* or refer to an error when happened */
|
||||
Result<List<QuizData>> getQuizzes(FilterMap filterMap);
|
||||
|
||||
/** Get all QuizData for the set of QuizData identifiers from LMS API in a collection
|
||||
* of Result. If particular Quiz cannot be loaded because of errors or deletion,
|
||||
* the Result will have an error reference.
|
||||
*
|
||||
* @param ids the Set of Quiz identifiers to get the QuizData for
|
||||
* @return Collection of all QuizData from the given id set */
|
||||
Collection<Result<QuizData>> getQuizzes(Set<String> ids);
|
||||
|
||||
Result<ExamineeAccountDetails> getExamineeAccountDetails(String examineeUserId);
|
||||
// TODO this can be used in a future release to resolve examinee's account detail information by an
|
||||
// examinee identifier received by on SEB-Client connection.
|
||||
//Result<ExamineeAccountDetails> getExamineeAccountDetails(String examineeUserId);
|
||||
|
||||
default List<APIMessage> attributeValidation(final ClientCredentials credentials) {
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
|||
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.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.client.ClientCredentialService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials;
|
||||
|
@ -50,27 +49,28 @@ final class MockupLmsAPITemplate implements LmsAPITemplate {
|
|||
this.clientCredentialService = clientCredentialService;
|
||||
this.credentials = credentials;
|
||||
|
||||
final String lmsSetupId = lmsSetup.getModelId();
|
||||
this.mockups = new ArrayList<>();
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz1", "Demo Quiz 1", "Demo Quit Mockup",
|
||||
"quiz1", lmsSetupId, "Demo Quiz 1", "Demo Quit Mockup",
|
||||
"2020-01-01 09:00:00", "2021-01-01 09:00:00", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz2", "Demo Quiz 2", "Demo Quit Mockup",
|
||||
"quiz2", lmsSetupId, "Demo Quiz 2", "Demo Quit Mockup",
|
||||
"2020-01-01 09:00:00", "2021-01-01 09:00:00", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz3", "Demo Quiz 3", "Demo Quit Mockup",
|
||||
"quiz3", lmsSetupId, "Demo Quiz 3", "Demo Quit Mockup",
|
||||
"2018-07-30 09:00:00", "2018-08-01 00:00:00", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz4", "Demo Quiz 4", "Demo Quit Mockup",
|
||||
"quiz4", lmsSetupId, "Demo Quiz 4", "Demo Quit Mockup",
|
||||
"2018-01-01 00:00:00", "2019-01-01 00:00:00", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz5", "Demo Quiz 5", "Demo Quit Mockup",
|
||||
"quiz5", lmsSetupId, "Demo Quiz 5", "Demo Quit Mockup",
|
||||
"2018-01-01 09:00:00", "2021-01-01 09:00:00", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz6", "Demo Quiz 6", "Demo Quit Mockup",
|
||||
"quiz6", lmsSetupId, "Demo Quiz 6", "Demo Quit Mockup",
|
||||
"2018-01-01 09:00:00", "2021-01-01 09:00:00", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz7", "Demo Quiz 7", "Demo Quit Mockup",
|
||||
"quiz7", lmsSetupId, "Demo Quiz 7", "Demo Quit Mockup",
|
||||
"2018-01-01 09:00:00", "2021-01-01 09:00:00", "http://lms.mockup.com/api/"));
|
||||
}
|
||||
|
||||
|
@ -124,16 +124,6 @@ final class MockupLmsAPITemplate implements LmsAPITemplate {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<ExamineeAccountDetails> getExamineeAccountDetails(final String examineeUserId) {
|
||||
authenticate();
|
||||
if (this.credentials == null) {
|
||||
throw new IllegalArgumentException("Wrong clientId or secret");
|
||||
}
|
||||
|
||||
return Result.of(new ExamineeAccountDetails(examineeUserId, "mockup", "mockup", "mockup"));
|
||||
}
|
||||
|
||||
private boolean authenticate() {
|
||||
try {
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
|||
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.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.SupplierWithCircuitBreaker;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialService;
|
||||
|
@ -136,12 +135,6 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<ExamineeAccountDetails> getExamineeAccountDetails(final String examineeUserId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
private Result<LmsSetup> initRestTemplateAndRequestAccessToken() {
|
||||
|
||||
log.info("Initialize Rest Template for OpenEdX API access. LmsSetup: {}", this.lmsSetup);
|
||||
|
@ -247,6 +240,7 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate {
|
|||
final String startURI = lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX + courseData.id;
|
||||
return new QuizData(
|
||||
courseData.id,
|
||||
lmsSetup.getModelId(),
|
||||
courseData.name,
|
||||
courseData.short_description,
|
||||
courseData.start,
|
||||
|
|
|
@ -34,6 +34,11 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
||||
|
||||
/** Abstract Entity-Controller that defines generic Entity rest API endpoints that are supported
|
||||
* by all entity types that has activation feature and can be activated or deactivated.
|
||||
*
|
||||
* @param <T> The concrete Entity domain-model type used on all GET, PUT
|
||||
* @param <M> The concrete Entity domain-model type used for POST methods (new) */
|
||||
public abstract class ActivatableEntityController<T extends GrantEntity, M extends GrantEntity>
|
||||
extends EntityController<T, M> {
|
||||
|
||||
|
|
|
@ -50,6 +50,11 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
|||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
||||
|
||||
/** Abstract Entity-Controller that defines generic Entity rest API endpoints that are supported
|
||||
* by all entity types.
|
||||
*
|
||||
* @param <T> The concrete Entity domain-model type used on all GET, PUT
|
||||
* @param <M> The concrete Entity domain-model type used for POST methods (new) */
|
||||
public abstract class EntityController<T extends GrantEntity, M extends GrantEntity> {
|
||||
|
||||
protected final AuthorizationService authorization;
|
||||
|
@ -75,6 +80,11 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
this.beanValidationService = beanValidationService;
|
||||
}
|
||||
|
||||
/** This is called by Spring to initialize the WebDataBinder and is used here to
|
||||
* initialize the default value binding for the institutionId request-parameter
|
||||
* that has the current users insitutionId as default.
|
||||
*
|
||||
* See also UserService.addUsersInstitutionDefaultPropertySupport */
|
||||
@InitBinder
|
||||
public void initBinder(final WebDataBinder binder) throws Exception {
|
||||
this.authorization
|
||||
|
@ -83,14 +93,32 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
}
|
||||
|
||||
// ******************
|
||||
// * GET (all)
|
||||
// * GET (getAll)
|
||||
// ******************
|
||||
|
||||
/** The get-all or get-page rest endpoint for all types of Entity and returns a Page of
|
||||
* entities of specific type.
|
||||
*
|
||||
* GET /{api}/{entity-type-endpoint-name}
|
||||
*
|
||||
* GET /admin-api/v1/exam
|
||||
* GET /admin-api/v1/exam?page_number=2&page_size=10&sort=-name
|
||||
* GET /admin-api/v1/exam?name=seb&active=true
|
||||
*
|
||||
* @param institutionId The institution identifier of the request.
|
||||
* Default is the institution identifier of the institution of the current user
|
||||
* @param pageNumber the number of the page that is requested
|
||||
* @param pageSize the size of the page that is requested
|
||||
* @param sort the sort parameter to sort the list of entities before paging
|
||||
* the sort parameter is the name of the entity-model attribute to sort with a leading '-' sign for
|
||||
* descending sort order
|
||||
* @param allRequestParams a MultiValueMap of all request parameter that is used for filtering
|
||||
* @return Page of domain-model-entities of specified type */
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Page<T> getAll(
|
||||
public Page<T> getPage(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
|
@ -363,8 +391,6 @@ public abstract class EntityController<T extends GrantEntity, M extends GrantEnt
|
|||
|
||||
protected abstract M createNew(POSTMapper postParams);
|
||||
|
||||
protected abstract Class<M> modifiedDataType();
|
||||
|
||||
protected abstract SqlTable getSQLTableOfEntity();
|
||||
|
||||
}
|
||||
|
|
|
@ -87,11 +87,6 @@ public class ExamAdministrationController extends ActivatableEntityController<Ex
|
|||
this.lmsAPIService = lmsAPIService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<Exam> modifiedDataType() {
|
||||
return Exam.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlTable getSQLTableOfEntity() {
|
||||
return ExamRecordDynamicSqlSupport.examRecord;
|
||||
|
@ -102,7 +97,7 @@ public class ExamAdministrationController extends ActivatableEntityController<Ex
|
|||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Override
|
||||
public Page<Exam> getAll(
|
||||
public Page<Exam> getPage(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
|
@ -120,7 +115,7 @@ public class ExamAdministrationController extends ActivatableEntityController<Ex
|
|||
if (StringUtils.isBlank(sort) ||
|
||||
this.paginationService.isNativeSortingSupported(ExamRecordDynamicSqlSupport.examRecord, sort)) {
|
||||
|
||||
return super.getAll(institutionId, pageNumber, pageSize, sort, allRequestParams);
|
||||
return super.getPage(institutionId, pageNumber, pageSize, sort, allRequestParams);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
|
@ -65,11 +65,6 @@ public class InstitutionController extends ActivatableEntityController<Instituti
|
|||
this.sebClientConfigService = sebClientConfigService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<Institution> modifiedDataType() {
|
||||
return Institution.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlTable getSQLTableOfEntity() {
|
||||
return InstitutionRecordDynamicSqlSupport.institutionRecord;
|
||||
|
|
|
@ -58,11 +58,6 @@ public class LmsSetupController extends ActivatableEntityController<LmsSetup, Lm
|
|||
this.lmsAPIService = lmsAPIService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<LmsSetup> modifiedDataType() {
|
||||
return LmsSetup.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlTable getSQLTableOfEntity() {
|
||||
return LmsSetupRecordDynamicSqlSupport.lmsSetupRecord;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
@ -29,7 +30,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
|||
|
||||
@WebServiceProfile
|
||||
@RestController
|
||||
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + API.QUIZ_IMPORT_ENDPOINT)
|
||||
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + API.QUIZ_DISCOVERY_ENDPOINT)
|
||||
public class QuizImportController {
|
||||
|
||||
private final int defaultPageSize;
|
||||
|
@ -50,8 +51,11 @@ public class QuizImportController {
|
|||
this.authorization = authorization;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public Page<QuizData> search(
|
||||
@RequestMapping(
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Page<QuizData> getQuizPage(
|
||||
@RequestParam(
|
||||
name = Entity.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
|
|
|
@ -90,11 +90,6 @@ public class UserAccountController extends ActivatableEntityController<UserInfo,
|
|||
.getUserInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<UserMod> modifiedDataType() {
|
||||
return UserMod.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlTable getSQLTableOfEntity() {
|
||||
return UserRecordDynamicSqlSupport.userRecord;
|
||||
|
|
|
@ -25,7 +25,7 @@ import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
|||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestServiceImpl;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.OAuth2AuthorizationContextHolder;
|
||||
|
||||
public class RestServiceTest extends GuiIntegrationTest {
|
||||
|
@ -36,7 +36,7 @@ public class RestServiceTest extends GuiIntegrationTest {
|
|||
final Collection<RestCall<?>> calls = new ArrayList<>();
|
||||
calls.add(new RestServiceTest.GetInstitution());
|
||||
|
||||
final RestService restService = new RestService(authorizationContextHolder, new JSONMapper(), calls);
|
||||
final RestServiceImpl restService = new RestServiceImpl(authorizationContextHolder, new JSONMapper(), calls);
|
||||
|
||||
final Result<Institution> call = restService.getBuilder(RestServiceTest.GetInstitution.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, "2")
|
||||
|
|
Loading…
Reference in a new issue