improved SEB Restriction handling error handling and logging
This commit is contained in:
		
							parent
							
								
									0544d7a799
								
							
						
					
					
						commit
						fc310597e6
					
				
					 19 changed files with 77 additions and 139 deletions
				
			
		|  | @ -177,9 +177,7 @@ public final class CircuitBreaker<T> { | |||
| 
 | ||||
|                 this.state = State.HALF_OPEN; | ||||
|                 this.failingCount.set(0); | ||||
|                 return Result.ofError(new RuntimeException( | ||||
|                         "Set CircuitBeaker to half-open state. Cause: " + result.getError(), | ||||
|                         result.getError())); | ||||
|                 return result; | ||||
|             } else { | ||||
|                 // try again | ||||
|                 return protectedRun(supplier); | ||||
|  | @ -258,7 +256,7 @@ public final class CircuitBreaker<T> { | |||
|             return Result.ofError(e); | ||||
|         } catch (final ExecutionException e) { | ||||
|             future.cancel(false); | ||||
|             if (log.isWarnEnabled()) { | ||||
|             if (log.isDebugEnabled()) { | ||||
|                 log.warn("Attempt error: {}, {}", e.getMessage(), this.state); | ||||
|             } | ||||
|             final Throwable cause = e.getCause(); | ||||
|  |  | |||
|  | @ -142,7 +142,8 @@ public final class Result<T> { | |||
|             if (this.error instanceof RuntimeException) { | ||||
|                 throw (RuntimeException) this.error; | ||||
|             } else { | ||||
|                 throw new RuntimeException("RuntimeExceptionWrapper cause: " + this.error.getMessage(), this.error); | ||||
|                 String cause = this.error.getMessage() != null ? this.error.getMessage() : this.error.toString(); | ||||
|                 throw new RuntimeException("RuntimeExceptionWrapper cause: " + cause, this.error); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -238,7 +238,7 @@ public class ExamForm implements TemplateComposer { | |||
|                 .withURIVariable(API.PARAM_MODEL_ID, exam.getModelId()) | ||||
|                 .call() | ||||
|                 .onError(e -> log.error("Unexpected error while trying to verify seb restriction settings: ", e)) | ||||
|                 .getOr(false); | ||||
|                 .getOr(exam.sebRestriction); | ||||
|         final boolean sebRestrictionMismatch = readonly && | ||||
|                 sebRestrictionAvailable && | ||||
|                 isRestricted != exam.sebRestriction && | ||||
|  | @ -525,7 +525,6 @@ public class ExamForm implements TemplateComposer { | |||
|         final boolean newExam = exam.id == null; | ||||
|         final boolean hasLMS = exam.lmsSetupId != null; | ||||
|         final boolean importFromLMS = newExam && hasLMS; | ||||
|         final DateTimeZone timeZone = this.pageService.getCurrentUser().get().timeZone; | ||||
|         final LocTextKey statusTitle = new LocTextKey("sebserver.exam.status." + exam.status.name()); | ||||
| 
 | ||||
|         return this.pageService.formBuilder(formContext.copyOf(content)) | ||||
|  | @ -585,9 +584,7 @@ public class ExamForm implements TemplateComposer { | |||
|                                 exam.getDescription()) | ||||
|                         .asArea() | ||||
|                         .readonly(hasLMS)) | ||||
|                 .withAdditionalValueMapping( | ||||
|                         QuizData.QUIZ_ATTR_DESCRIPTION, | ||||
|                         QuizData.QUIZ_ATTR_DESCRIPTION) | ||||
|                 .withAdditionalValueMapping(QuizData.QUIZ_ATTR_DESCRIPTION) | ||||
| 
 | ||||
|                 .addField(FormBuilder.dateTime( | ||||
|                                 Domain.EXAM.ATTR_QUIZ_START_TIME, | ||||
|  | @ -599,11 +596,8 @@ public class ExamForm implements TemplateComposer { | |||
|                 .addField(FormBuilder.dateTime( | ||||
|                                 Domain.EXAM.ATTR_QUIZ_END_TIME, | ||||
|                                 FORM_END_TIME_TEXT_KEY, | ||||
|                                 exam.endTime != null | ||||
|                                         ? exam.endTime | ||||
|                                         : DateTime.now(timeZone).plusHours(1)) | ||||
|                         .readonly(hasLMS) | ||||
|                         .mandatory(!hasLMS)) | ||||
|                                 exam.endTime) | ||||
|                         .readonly(hasLMS)) | ||||
| 
 | ||||
|                 .addField(FormBuilder.text( | ||||
|                                 QuizData.QUIZ_ATTR_START_URL, | ||||
|  | @ -611,9 +605,7 @@ public class ExamForm implements TemplateComposer { | |||
|                                 exam.getStartURL()) | ||||
|                         .readonly(hasLMS) | ||||
|                         .mandatory(!hasLMS)) | ||||
|                 .withAdditionalValueMapping( | ||||
|                         QuizData.QUIZ_ATTR_START_URL, | ||||
|                         QuizData.QUIZ_ATTR_START_URL) | ||||
|                 .withAdditionalValueMapping(QuizData.QUIZ_ATTR_START_URL) | ||||
| 
 | ||||
|                 .addField(FormBuilder.singleSelection( | ||||
|                                 Domain.EXAM.ATTR_TYPE, | ||||
|  | @ -636,6 +628,7 @@ public class ExamForm implements TemplateComposer { | |||
|     } | ||||
| 
 | ||||
|     private Exam newExamNoLMS() { | ||||
|         final DateTimeZone timeZone = this.pageService.getCurrentUser().get().timeZone; | ||||
|         return new Exam( | ||||
|             null, | ||||
|             this.pageService.getCurrentUser().get().institutionId, | ||||
|  | @ -643,8 +636,8 @@ public class ExamForm implements TemplateComposer { | |||
|             UUID.randomUUID().toString(), | ||||
|             true, | ||||
|             null, | ||||
|             null, | ||||
|             null, | ||||
|                 DateTime.now(timeZone), | ||||
|                 DateTime.now(timeZone).plusHours(1), | ||||
|             Exam.ExamType.UNDEFINED, | ||||
|             null, | ||||
|             null, | ||||
|  |  | |||
|  | @ -23,10 +23,11 @@ public class DateTimeSelectorFieldBuilder extends FieldBuilder<DateTime> { | |||
|         final Composite fieldGrid = createFieldGrid(builder.formParent, this.spanInput); | ||||
| 
 | ||||
|         if (readonly) { | ||||
|             final Text label = new Text(fieldGrid, SWT.NONE); | ||||
|             label.setText(builder.i18nSupport.formatDisplayDateTime(value) + " " + builder.i18nSupport.getUsersTimeZoneTitleSuffix()); | ||||
|             label.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); | ||||
|             builder.form.putReadonlyField(this.name, titleLabel, label); | ||||
|             final Text readonlyLabel = builder.widgetFactory.textInput(fieldGrid, this.label); | ||||
|             readonlyLabel.setEditable(false); | ||||
|             readonlyLabel.setText(builder.i18nSupport.formatDisplayDateWithTimeZone(value)); | ||||
|             readonlyLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true)); | ||||
|             builder.form.putReadonlyField(this.name, titleLabel, readonlyLabel); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,7 +16,6 @@ import java.util.function.Predicate; | |||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.api.API; | ||||
| import ch.ethz.seb.sebserver.gui.widget.*; | ||||
| import com.fasterxml.jackson.databind.JsonNode; | ||||
| import org.apache.commons.lang3.BooleanUtils; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.eclipse.rap.rwt.RWT; | ||||
|  | @ -105,6 +104,10 @@ public final class Form implements FormBinding { | |||
|         this.additionalAttributeMapping.put(fieldName, attrName); | ||||
|     } | ||||
| 
 | ||||
|     public void putAdditionalValueMapping(final String fieldName) { | ||||
|         this.additionalAttributeMapping.put(fieldName, fieldName); | ||||
|     } | ||||
| 
 | ||||
|     public String getStaticValue(final String name) { | ||||
|         return this.staticValues.get(name); | ||||
|     } | ||||
|  | @ -188,7 +191,7 @@ public final class Form implements FormBinding { | |||
|     Form removeField(final String name) { | ||||
|         if (this.formFields.containsKey(name)) { | ||||
|             final List<FormFieldAccessor> list = this.formFields.remove(name); | ||||
|             list.forEach(ffa -> ffa.dispose()); | ||||
|             list.forEach(FormFieldAccessor::dispose); | ||||
|         } | ||||
| 
 | ||||
|         return this; | ||||
|  | @ -318,7 +321,7 @@ public final class Form implements FormBinding { | |||
|                     additionalAttrs.put(entry.getValue(), fieldValue); | ||||
|                 } | ||||
|             } | ||||
|             if (additionalAttrs != null) { | ||||
|             if (!additionalAttrs.isEmpty()) { | ||||
|                 this.objectRoot.putIfAbsent( | ||||
|                         API.PARAM_ADDITIONAL_ATTRIBUTES, | ||||
|                         jsonMapper.valueToTree(additionalAttrs)); | ||||
|  |  | |||
|  | @ -152,6 +152,21 @@ public class FormBuilder { | |||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     public FormBuilder withAdditionalValueMapping(final String fieldName) { | ||||
|         this.form.putAdditionalValueMapping(fieldName); | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     public FormBuilder withAdditionalValueMappingIf( | ||||
|             final BooleanSupplier condition, | ||||
|             final Supplier<String> fieldNameSupplier) { | ||||
| 
 | ||||
|         if (condition.getAsBoolean()) { | ||||
|             this.form.putAdditionalValueMapping(fieldNameSupplier.get()); | ||||
|         } | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     public FormBuilder addFieldIf( | ||||
|             final BooleanSupplier condition, | ||||
|             final Supplier<FieldBuilder<?>> templateSupplier) { | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.i18n; | |||
| import java.util.Collection; | ||||
| import java.util.Locale; | ||||
| 
 | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.joda.time.DateTime; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.util.Utils; | ||||
|  | @ -61,7 +62,9 @@ public interface I18nSupport { | |||
|      * @param date the DateTime instance | ||||
|      * @return date formatted date String to display */ | ||||
|     default String formatDisplayDateWithTimeZone(final DateTime date) { | ||||
|         return formatDisplayDateTime(date) + " " + this.getUsersTimeZoneTitleSuffix(); | ||||
|         return formatDisplayDateTime(date) + (date != null | ||||
|                 ? " " + this.getUsersTimeZoneTitleSuffix() | ||||
|                 : StringUtils.EMPTY); | ||||
|     } | ||||
| 
 | ||||
|     /** Format a time-stamp (milliseconds) to a text format to display. | ||||
|  |  | |||
|  | @ -124,7 +124,7 @@ public class ExamAdminServiceImpl implements ExamAdminService { | |||
|                     EntityType.EXAM, | ||||
|                     examId, | ||||
|                     Exam.ADDITIONAL_ATTR_SIGNATURE_KEY_SALT, | ||||
|                     KeyGenerators.string().generateKey().toString()); | ||||
|                     KeyGenerators.string().generateKey()); | ||||
| 
 | ||||
|             return exam; | ||||
|         }).flatMap(this::initAdditionalAttributesForMoodleExams); | ||||
|  | @ -204,7 +204,7 @@ public class ExamAdminServiceImpl implements ExamAdminService { | |||
|         return this.lmsAPIService | ||||
|                 .getLmsAPITemplate(exam.lmsSetupId) | ||||
|                 .map(lmsAPI -> lmsAPI.hasSEBClientRestriction(exam)) | ||||
|                 .onError(error -> log.error("Failed to check SEB restriction: ", error)); | ||||
|                 .onError(error -> log.warn("Failed to check SEB restriction: {}", error.getMessage())); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -301,7 +301,7 @@ public class ExamAdminServiceImpl implements ExamAdminService { | |||
| 
 | ||||
|         return getProctoringServiceSettings(exam.id) | ||||
|                 .map(settings -> { | ||||
|                     ProctoringServiceSettings resetSettings; | ||||
|                     final ProctoringServiceSettings resetSettings; | ||||
|                     if (exam.examTemplateId != null) { | ||||
|                         // get settings from origin template | ||||
|                         resetSettings = this.proctoringAdminService | ||||
|  | @ -401,7 +401,7 @@ public class ExamAdminServiceImpl implements ExamAdminService { | |||
|                     .stream() | ||||
|                     .forEach(configNodeId -> { | ||||
|                         if (this.examConfigurationMapDAO.checkNoActiveExamReferences(configNodeId).getOr(false)) { | ||||
|                             log.debug("Also set exam configuration to archived: ", configNodeId); | ||||
|                             log.debug("Also set exam configuration to archived: {}", configNodeId); | ||||
|                             this.configurationNodeDAO.save( | ||||
|                                     new ConfigurationNode( | ||||
|                                             configNodeId, null, null, null, null, null, | ||||
|  |  | |||
|  | @ -23,18 +23,18 @@ public interface SEBRestrictionAPI { | |||
|      * @return {@link LmsSetupTestResult } instance with the test result report */ | ||||
|     LmsSetupTestResult testCourseRestrictionAPI(); | ||||
| 
 | ||||
|     /** Get SEB restriction data from LMS within a {@link SEBRestrictionData } instance. The available restriction | ||||
|     /** Get SEB restriction data from LMS within a {@link SEBRestriction } instance. The available restriction | ||||
|      * details | ||||
|      * depends on the type of LMS but shall at least contains the config-key(s) and the browser-exam-key(s). | ||||
|      * | ||||
|      * @param exam the exam to get the SEB restriction data for | ||||
|      * @return Result refer to the {@link SEBRestrictionData } instance or to an ResourceNotFoundException if the | ||||
|      * @return Result refer to the {@link SEBRestriction } instance or to an ResourceNotFoundException if the | ||||
|      *         restriction is | ||||
|      *         missing or to another exception on unexpected error case */ | ||||
|     Result<SEBRestriction> getSEBClientRestriction(Exam exam); | ||||
| 
 | ||||
|     /** Use this to check if there is a SEB restriction available on the LMS for the specified exam. | ||||
|      * | ||||
|      * <p> | ||||
|      * A SEB Restriction is available if it can get from LMS and if there is either a Config-Key | ||||
|      * or a BrowserExam-Key set or both. If none of this keys is set, the SEB Restriction is been | ||||
|      * considered to not set on the LMS. | ||||
|  | @ -42,12 +42,7 @@ public interface SEBRestrictionAPI { | |||
|      * @param exam exam the exam to get the SEB restriction data for | ||||
|      * @return true if there is a SEB restriction set on the LMS for the exam or false otherwise */ | ||||
|     default boolean hasSEBClientRestriction(final Exam exam) { | ||||
|         final Result<SEBRestriction> sebClientRestriction = getSEBClientRestriction(exam); | ||||
|         if (sebClientRestriction.hasError()) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return hasSEBClientRestriction(sebClientRestriction.get()); | ||||
|         return hasSEBClientRestriction(getSEBClientRestriction(exam).getOrThrow()); | ||||
|     } | ||||
| 
 | ||||
|     default boolean hasSEBClientRestriction(final SEBRestriction sebRestriction) { | ||||
|  | @ -58,7 +53,7 @@ public interface SEBRestrictionAPI { | |||
|      * | ||||
|      * @param exam The exam to apply the restriction for | ||||
|      * @param sebRestrictionData containing all data for SEB Client restriction to apply to the LMS | ||||
|      * @return Result refer to the given {@link SEBRestrictionData } if restriction was successful or to an error if | ||||
|      * @return Result refer to the given {@link SEBRestriction } if restriction was successful or to an error if | ||||
|      *         not */ | ||||
|     Result<SEBRestriction> applySEBClientRestriction( | ||||
|             Exam exam, | ||||
|  |  | |||
|  | @ -153,8 +153,11 @@ public class LmsAPIServiceImpl implements LmsAPIService { | |||
|         } | ||||
| 
 | ||||
|         if (template.lmsSetup().getLmsType().features.contains(LmsSetup.Features.SEB_RESTRICTION)) { | ||||
|             final LmsSetupTestResult lmsSetupTestResult = template.testCourseRestrictionAPI(); | ||||
|             if (!lmsSetupTestResult.isOk()) { | ||||
|                 this.cache.remove(new CacheKey(template.lmsSetup().getModelId(), 0)); | ||||
|             return template.testCourseRestrictionAPI(); | ||||
|             } | ||||
|             return lmsSetupTestResult; | ||||
|         } | ||||
| 
 | ||||
|         return LmsSetupTestResult.ofOkay(template.lmsSetup().getLmsType()); | ||||
|  |  | |||
|  | @ -386,18 +386,12 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate { | |||
| 
 | ||||
|         return this.restrictionRequest.protectedRun(() -> this.sebRestrictionAPI | ||||
|                 .getSEBClientRestriction(exam) | ||||
|                 .onError(error -> log.error("Failed to get SEB restrictions: {}", error.getMessage())) | ||||
|                 .getOrThrow()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean hasSEBClientRestriction(final Exam exam) { | ||||
|         final Result<SEBRestriction> sebClientRestriction = getSEBClientRestriction(exam); | ||||
|         if (sebClientRestriction.hasError()) { | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return this.sebRestrictionAPI.hasSEBClientRestriction(sebClientRestriction.get()); | ||||
|         return this.sebRestrictionAPI.hasSEBClientRestriction(getSEBClientRestriction(exam).getOrThrow()); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ import java.util.Map; | |||
| import java.util.Set; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.AdditionalAttributeRecord; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | @ -102,7 +103,7 @@ public class SEBRestrictionServiceImpl implements SEBRestrictionService { | |||
|                     .getOrThrow(); | ||||
| 
 | ||||
|             configKeys.addAll(generatedKeys); | ||||
|             if (generatedKeys != null && !generatedKeys.isEmpty()) { | ||||
|             if (!generatedKeys.isEmpty()) { | ||||
|                 configKeys.addAll(this.lmsAPIService | ||||
|                         .getLmsAPITemplate(exam.lmsSetupId) | ||||
|                         .flatMap(lmsTemplate -> lmsTemplate.getSEBClientRestriction(exam)) | ||||
|  | @ -130,8 +131,8 @@ public class SEBRestrictionServiceImpl implements SEBRestrictionService { | |||
|                         .collect(Collectors.toMap( | ||||
|                                 attr -> attr.getName().replace( | ||||
|                                         SEB_RESTRICTION_ADDITIONAL_PROPERTY_NAME_PREFIX, | ||||
|                                         ""), | ||||
|                                 attr -> attr.getValue()))); | ||||
|                                         StringUtils.EMPTY), | ||||
|                                 AdditionalAttributeRecord::getValue))); | ||||
|             } catch (final Exception e) { | ||||
|                 log.error( | ||||
|                         "Failed to load additional SEB restriction properties from AdditionalAttributes of the Exam: {}", | ||||
|  |  | |||
|  | @ -8,6 +8,10 @@ | |||
| 
 | ||||
| package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.mockup; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
|  | @ -23,6 +27,8 @@ public class MockSEBRestrictionAPI implements SEBRestrictionAPI { | |||
| 
 | ||||
|     private static final Logger log = LoggerFactory.getLogger(MockSEBRestrictionAPI.class); | ||||
| 
 | ||||
|     //private Map<Long, Boolean> restrictionDB = new ConcurrentHashMap<>(); | ||||
| 
 | ||||
|     @Override | ||||
|     public LmsSetupTestResult testCourseRestrictionAPI() { | ||||
|         return LmsSetupTestResult.ofOkay(LmsType.MOCKUP); | ||||
|  | @ -31,15 +37,6 @@ public class MockSEBRestrictionAPI implements SEBRestrictionAPI { | |||
|     @Override | ||||
|     public Result<SEBRestriction> getSEBClientRestriction(final Exam exam) { | ||||
|         log.info("Get SEB Client restriction for Exam: {}", exam); | ||||
| //        if (BooleanUtils.toBoolean(exam.sebRestriction)) { | ||||
| //            return Result.of(new SEBRestriction( | ||||
| //                    exam.id, | ||||
| //                    Stream.of("configKey").collect(Collectors.toList()), | ||||
| //                    Collections.emptyList(), | ||||
| //                    Collections.emptyMap())); | ||||
| //        } else { | ||||
| //            return Result.ofError(new NoSEBRestrictionException()); | ||||
| //        } | ||||
|         return Result.ofError(new NoSEBRestrictionException()); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -164,7 +164,6 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory | |||
|     public Result<MoodleAPIRestTemplate> createRestTemplate(final String service, final String accessTokenPath) { | ||||
| 
 | ||||
|         final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup(); | ||||
| 
 | ||||
|         return Result.tryCatch(() -> { | ||||
|             final ClientCredentials credentials = this.apiTemplateDataSupplier.getLmsClientCredentials(); | ||||
|             final ProxyData proxyData = this.apiTemplateDataSupplier.getProxyData(); | ||||
|  | @ -319,7 +318,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory | |||
|             } | ||||
| 
 | ||||
|             final boolean usePOST = queryAttributes != null && !queryAttributes.isEmpty(); | ||||
|             HttpEntity<?> functionReqEntity; | ||||
|             final HttpEntity<?> functionReqEntity; | ||||
|             if (usePOST) { | ||||
|                 final HttpHeaders headers = new HttpHeaders(); | ||||
|                 headers.set( | ||||
|  | @ -401,8 +400,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory | |||
|                     if (moodleToken == null || moodleToken.token == null) { | ||||
|                         throw new RuntimeException("Access Token request with 200 but no or invalid token body"); | ||||
|                     } else { | ||||
|                         log.info("Successfully get access token from Moodle: {}", | ||||
|                                 lmsSetup); | ||||
|                         log.info("Successfully get access token from Moodle: {}", lmsSetup.name); | ||||
|                     } | ||||
| 
 | ||||
|                     this.accessToken = moodleToken.token; | ||||
|  |  | |||
|  | @ -1,68 +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.plugin; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.context.annotation.Lazy; | ||||
| import org.springframework.stereotype.Service; | ||||
| 
 | ||||
| import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult; | ||||
| import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate; | ||||
| import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory; | ||||
| 
 | ||||
| @Lazy | ||||
| @Service | ||||
| @WebServiceProfile | ||||
| public class MoodlePluginCheck { | ||||
| 
 | ||||
|     private static final Logger log = LoggerFactory.getLogger(MoodlePluginCheck.class); | ||||
| 
 | ||||
|     /** Used to check if the moodle SEB Server plugin is available for a given LMSSetup. | ||||
|      * | ||||
|      * @param lmsSetup The LMS Setup | ||||
|      * @return true if the SEB Server plugin is available */ | ||||
|     public boolean checkPluginAvailable(final MoodleRestTemplateFactory restTemplateFactory) { | ||||
|         try { | ||||
| 
 | ||||
|             log.info("Check Moodle SEB Server Plugin available..."); | ||||
| 
 | ||||
|             final LmsSetupTestResult test = restTemplateFactory.test(); | ||||
| 
 | ||||
|             if (!test.isOk()) { | ||||
|                 log.warn("Failed to check Moodle SEB Server Plugin because of invalid LMS Setup: ", test); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             final MoodleAPIRestTemplate restTemplate = restTemplateFactory | ||||
|                     .createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME) | ||||
|                     .getOrThrow(); | ||||
| 
 | ||||
|             try { | ||||
|                 restTemplate.testAPIConnection( | ||||
|                         MoodlePluginCourseAccess.COURSES_API_FUNCTION_NAME, | ||||
|                         MoodlePluginCourseAccess.USERS_API_FUNCTION_NAME); | ||||
|             } catch (final Exception e) { | ||||
|                 log.info("Moodle SEB Server Plugin not available: {}", e.getMessage()); | ||||
|                 return false; | ||||
|             } | ||||
| 
 | ||||
|             log.info("Moodle SEB Server Plugin not available for: {}", | ||||
|                     restTemplateFactory.getApiTemplateDataSupplier().getLmsSetup()); | ||||
| 
 | ||||
|             return true; | ||||
| 
 | ||||
|         } catch (final Exception e) { | ||||
|             log.error("Failed to check Moodle SEB Server Plugin because of unexpected error: ", e); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -109,6 +109,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme | |||
|             final boolean applyNameCriteria) { | ||||
| 
 | ||||
|         super(cacheManager); | ||||
| 
 | ||||
|         this.jsonMapper = jsonMapper; | ||||
|         this.restTemplateFactory = restTemplateFactory; | ||||
|         this.applyNameCriteria = applyNameCriteria; | ||||
|  | @ -594,7 +595,9 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme | |||
|     } | ||||
| 
 | ||||
|     private Result<MoodleAPIRestTemplate> getRestTemplate() { | ||||
| 
 | ||||
|         if (this.restTemplate == null) { | ||||
| 
 | ||||
|             final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory | ||||
|                     .createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME); | ||||
|             if (templateRequest.hasError()) { | ||||
|  |  | |||
|  | @ -283,13 +283,13 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI { | |||
| 
 | ||||
|     private Result<MoodleAPIRestTemplate> getRestTemplate() { | ||||
|         if (this.restTemplate == null) { | ||||
| 
 | ||||
|             final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory | ||||
|                     .createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME); | ||||
|             if (templateRequest.hasError()) { | ||||
|                 return templateRequest; | ||||
|             } else { | ||||
|                 final MoodleAPIRestTemplate moodleAPIRestTemplate = templateRequest.get(); | ||||
|                 this.restTemplate = moodleAPIRestTemplate; | ||||
|                 this.restTemplate = templateRequest.get(); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  |  | |||
|  | @ -337,7 +337,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> { | |||
|         return this.examDAO | ||||
|                 .byPK(modelId) | ||||
|                 .flatMap(this.examAdminService::isRestricted) | ||||
|                 .getOrThrow(); | ||||
|                 .getOr(false); | ||||
|     } | ||||
| 
 | ||||
|     @RequestMapping( | ||||
|  | @ -376,7 +376,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> { | |||
|         return this.entityDAO.byPK(examId) | ||||
|                 .flatMap(this.authorization::checkModify) | ||||
|                 .flatMap(exam -> this.sebRestrictionService.saveSEBRestrictionToExam(exam, sebRestriction)) | ||||
|                 .flatMap(exam -> this.examAdminService.isRestricted(exam).getOrThrow() | ||||
|                 .flatMap(exam -> this.examAdminService.isRestricted(exam).getOr(false) | ||||
|                         ? this.applySEBRestriction(exam, true) | ||||
|                         : Result.of(exam)) | ||||
|                 .getOrThrow(); | ||||
|  |  | |||
|  | @ -33,6 +33,7 @@ public class MoodlePluginCourseRestrictionTest { | |||
| 
 | ||||
|     @Test | ||||
|     public void testSetup() { | ||||
| 
 | ||||
|         final MoodlePluginCourseRestriction candidate = crateMockup(); | ||||
| 
 | ||||
|         assertEquals("MoodlePluginCourseRestriction [restTemplate=null]", candidate.toTestString()); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti