diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java index 7c54401b..4a82aa48 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java @@ -276,8 +276,6 @@ public class ExamList implements TemplateComposer { item.setData(RWT.CUSTOM_VARIANT, CustomVariant.WARNING.key); } }); - - item.setGrayed(true); } private static Function examLmsSetupNameFunction(final ResourceService resourceService) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java index f97ba552..2390b63c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java @@ -198,11 +198,11 @@ public interface ExamDAO extends ActivatableEntityDAO, BulkActionSup key = "#examId") Result updateQuizData(Long examId, QuizData quizData, String updateId); - /** This is used by the internal update process to mark exams for which the LMS related data is - * not currently available and the local data might be out-dated + /** This is used by the internal update process to mark exams for which the LMS related data availability * * @param externalQuizId The exams external UUID or quiz id of the exam to mark + * @param available The LMS availability flag to set * @param updateId The update identifier given by the update task */ - void markLMSNotAvailable(final String externalQuizId, final String updateId); + void markLMSAvailability(final String externalQuizId, final boolean available, final String updateId); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java index bae2bd3f..7b274a39 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java @@ -177,12 +177,16 @@ public class ExamDAOImpl implements ExamDAO { } @Override - public void markLMSNotAvailable(final String externalQuizId, final String updateId) { + public void markLMSAvailability(final String externalQuizId, final boolean available, final String updateId) { - log.info("Mark exam quiz data not available form LMS: {}", externalQuizId); + if (!available) { + log.info("Mark exam quiz data not available form LMS: {}", externalQuizId); + } else { + log.info("Mark exam quiz data back again form LMS: {}", externalQuizId); + } this.examRecordDAO.idByExternalQuizId(externalQuizId) - .map(examId -> this.examRecordDAO.updateLmsNotAvailable(examId, updateId)) + .flatMap(examId -> this.examRecordDAO.updateLmsNotAvailable(examId, available, updateId)) .onError(error -> log.error("Failed to mark LMS not available: {}", externalQuizId, error)); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamRecordDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamRecordDAO.java index 3aa02dd7..691729ef 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamRecordDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamRecordDAO.java @@ -283,7 +283,7 @@ public class ExamRecordDAO { } @Transactional - public Result updateLmsNotAvailable(final Long examId, final String updateId) { + public Result updateLmsNotAvailable(final Long examId, final boolean available, final String updateId) { return Result.tryCatch(() -> { // check internal persistent write-lock @@ -300,7 +300,7 @@ public class ExamRecordDAO { null, null, Utils.getMillisecondsNow(), null, null, null, - BooleanUtils.toIntegerObject(false)); + BooleanUtils.toIntegerObject(available)); this.examRecordMapper.updateByPrimaryKeySelective(examRecord); return this.examRecordMapper.selectByPrimaryKey(examId); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java index 343a57b3..537f2ceb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/mockup/MockCourseAccessAPI.java @@ -166,6 +166,7 @@ public class MockCourseAccessAPI implements CourseAccessAPI { public Result getQuiz(final String id) { return Result.of(this.mockups .stream() + .map(this::getExternalAddressAlias) .filter(q -> id.equals(q.id)) .findFirst() .get()); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java index 6c6324a9..0b4d1bb9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java @@ -8,6 +8,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl; +import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Objects; @@ -85,9 +86,14 @@ class ExamUpdateHandler { final Set failedOrMissing = new HashSet<>(exams.keySet()); final String updateId = this.createUpdateId(); - this.lmsAPIService.getLmsAPITemplate(lmsSetupId) + this.lmsAPIService + .getLmsAPITemplate(lmsSetupId) .flatMap(template -> template.getQuizzes(new HashSet<>(exams.keySet()))) - .getOrThrow() + .onError(error -> log.warn( + "Failed to get quizzes form LMS Setup: {} cause: {}", + lmsSetupId, + error.getMessage())) + .getOr(Collections.emptyList()) .stream() .forEach(quiz -> { @@ -102,11 +108,17 @@ class ExamUpdateHandler { log.error("Failed to update quiz data for exam: {}", quiz, updateQuizData.getError()); } else { + if (!exam.lmsAvailable) { + this.examDAO.markLMSAvailability(quiz.id, true, updateId); + } failedOrMissing.remove(quiz.id); log.info("Updated quiz data for exam: {}", updateQuizData.get()); } } else { + if (!exam.lmsAvailable) { + this.examDAO.markLMSAvailability(quiz.id, true, updateId); + } failedOrMissing.remove(quiz.id); } } catch (final Exception e) { @@ -214,6 +226,7 @@ class ExamUpdateHandler { final String updateId) { return Result.tryCatch(() -> { + final Exam exam = exams.get(quizId); final LmsAPITemplate lmsTemplate = this.lmsAPIService .getLmsAPITemplate(lmsSetupId) .getOrThrow(); @@ -230,7 +243,6 @@ class ExamUpdateHandler { log.info("Try to recover quiz data for Moodle quiz with internal identifier: {}", quizId); - final Exam exam = exams.get(quizId); if (exam != null && exam.name != null) { log.debug("Found formerName quiz name: {}", exam.name); @@ -270,7 +282,9 @@ class ExamUpdateHandler { } } - this.examDAO.markLMSNotAvailable(quizId, updateId); + if (exam.lmsAvailable) { + this.examDAO.markLMSAvailability(quizId, false, updateId); + } throw new RuntimeException("Not Available"); }); } diff --git a/src/main/resources/config/sql/base/V15__alterTables_v1_4.sql b/src/main/resources/config/sql/base/V15__alterTables_v1_4.sql index b89cb934..6edef22b 100644 --- a/src/main/resources/config/sql/base/V15__alterTables_v1_4.sql +++ b/src/main/resources/config/sql/base/V15__alterTables_v1_4.sql @@ -34,5 +34,5 @@ ALTER TABLE `exam` ADD COLUMN IF NOT EXISTS `quiz_name` VARCHAR(255) NULL AFTER `last_modified`, ADD COLUMN IF NOT EXISTS `quiz_start_time` DATETIME NULL AFTER `quiz_name`, ADD COLUMN IF NOT EXISTS `quiz_end_time` DATETIME NULL AFTER `quiz_start_time`, -ADD COLUMN IF NOT EXISTS `lms_available` INT(1) NULL AFTER `quiz_end_time`, +ADD COLUMN IF NOT EXISTS `lms_available` INT(1) NULL AFTER `quiz_end_time` ; \ No newline at end of file diff --git a/src/main/resources/static/css/sebserver.css b/src/main/resources/static/css/sebserver.css index 7c0a1e55..c41a0838 100644 --- a/src/main/resources/static/css/sebserver.css +++ b/src/main/resources/static/css/sebserver.css @@ -909,6 +909,11 @@ TableItem:linesvisible:even { color: inherit; } +TableItem:linesvisible:even.disabled { + background-color: #ffffff; + color: #aaaaaa; +} + Table-RowOverlay { background-color: transparent; color: inherit;