diff --git a/pom.xml b/pom.xml index bb0e4b3b..1d7cb3be 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ jar - 1.4.0 + 1.4.1 ${sebserver-version} ${sebserver-version} UTF-8 diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java b/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java index 18f1ed69..45095388 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java @@ -757,4 +757,18 @@ public final class Utils { } } + public static boolean isEqualsWithEmptyCheck(final String s1, final String s2) { + // checks equal strings and both null + if (Objects.equals(s1, s2)) { + return true; + } + + // check null and empty string + if (StringUtils.isBlank(s1) && StringUtils.isBlank(s2)) { + return true; + } + + return false; + } + } 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 dd17c5ff..847490b8 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 @@ -742,14 +742,20 @@ public class ExamDAOImpl implements ExamDAO { private QuizData saveAdditionalQuizAttributes(final Long examId, final QuizData quizData) { final Map additionalAttributes = new HashMap<>(quizData.getAdditionalAttributes()); - additionalAttributes.put(QuizData.QUIZ_ATTR_DESCRIPTION, quizData.description); - additionalAttributes.put(QuizData.QUIZ_ATTR_START_URL, quizData.startURL); + if (StringUtils.isNotBlank(quizData.description)) { + additionalAttributes.put(QuizData.QUIZ_ATTR_DESCRIPTION, quizData.description); + } + if (StringUtils.isNotBlank(quizData.startURL)) { + additionalAttributes.put(QuizData.QUIZ_ATTR_START_URL, quizData.startURL); + } - this.additionalAttributesDAO.saveAdditionalAttributes( - EntityType.EXAM, - examId, - additionalAttributes) - .getOrThrow(); + if (!additionalAttributes.isEmpty()) { + this.additionalAttributesDAO.saveAdditionalAttributes( + EntityType.EXAM, + examId, + additionalAttributes) + .getOrThrow(); + } return quizData; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java index fb0a9f82..63586188 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java @@ -135,8 +135,6 @@ public class UserDAOImpl implements UserDAO { this.userRecordMapper .selectByExample() .where(UserRecordDynamicSqlSupport.username, isEqualTo(username)) - .and(UserRecordDynamicSqlSupport.active, - isEqualTo(BooleanUtils.toInteger(true))) .build() .execute()) .flatMap(this::sebServerUserFromRecord); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/SEBRestrictionAPI.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/SEBRestrictionAPI.java index a88786ee..7667a4b3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/SEBRestrictionAPI.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/SEBRestrictionAPI.java @@ -35,7 +35,7 @@ public interface SEBRestrictionAPI { /** Use this to check if there is a SEB restriction available on the LMS for the specified exam. * - * A SEB Restriction is available if there it can get from LMS and if there is either a Config-Key + * 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. * diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/SEBRestrictionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/SEBRestrictionServiceImpl.java index 05c69b7f..417d6899 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/SEBRestrictionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/SEBRestrictionServiceImpl.java @@ -197,6 +197,7 @@ public class SEBRestrictionServiceImpl implements SEBRestrictionService { log.info("ExamStartedEvent received, process applySEBClientRestriction..."); applySEBClientRestriction(event.exam) + .flatMap(e -> this.examDAO.setSEBRestriction(e.id, true)) .onError(error -> log.error( "Failed to apply SEB restrictions for started exam: {}", event.exam, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamConfigUpdateServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamConfigUpdateServiceImpl.java index 3c369f10..b5576433 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamConfigUpdateServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamConfigUpdateServiceImpl.java @@ -29,7 +29,6 @@ import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamConfigurationMapDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamAdminService; import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamConfigUpdateService; import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService; @@ -45,22 +44,19 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService { private final ExamConfigurationMapDAO examConfigurationMapDAO; private final ExamSessionService examSessionService; private final ExamUpdateHandler examUpdateHandler; - private final ExamAdminService examAdminService; protected ExamConfigUpdateServiceImpl( final ExamDAO examDAO, final ConfigurationDAO configurationDAO, final ExamConfigurationMapDAO examConfigurationMapDAO, final ExamSessionService examSessionService, - final ExamUpdateHandler examUpdateHandler, - final ExamAdminService examAdminService) { + final ExamUpdateHandler examUpdateHandler) { this.examDAO = examDAO; this.configurationDAO = configurationDAO; this.examConfigurationMapDAO = examConfigurationMapDAO; this.examSessionService = examSessionService; this.examUpdateHandler = examUpdateHandler; - this.examAdminService = examAdminService; } // processing: @@ -129,11 +125,12 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService { // generate the new Config Key and update the Config Key within the LMSSetup API for each exam (delete old Key and add new Key) for (final Exam exam : exams) { - if (exam.getStatus() == ExamStatus.RUNNING || this.examAdminService.isRestricted(exam).getOr(false)) { + if (exam.getStatus() == ExamStatus.RUNNING) { this.examUpdateHandler .getSEBRestrictionService() .applySEBClientRestriction(exam) + .flatMap(e -> this.examDAO.setSEBRestriction(e.id, true)) .onError(t -> log.error("Failed to update SEB Client restriction for Exam: {}", exam, t)); } } @@ -201,15 +198,14 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService { .getOrThrow(); // update seb client restriction if the feature is activated for the exam - if (this.examAdminService.isRestricted(exam).getOr(false)) { - this.examUpdateHandler - .getSEBRestrictionService() - .applySEBClientRestriction(exam) - .onError(t -> log.error( - "Failed to update SEB Client restriction for Exam: {}", - exam, - t)); - } + this.examUpdateHandler + .getSEBRestrictionService() + .applySEBClientRestriction(exam) + .flatMap(e -> this.examDAO.setSEBRestriction(e.id, true)) + .onError(t -> log.error( + "Failed to update SEB Client restriction for Exam: {}", + exam, + t)); // flush the exam cache. If there was an error during flush, it is logged but this process goes on // and the saved changes are not rolled back 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 d911846c..b792fe8f 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 @@ -338,18 +338,29 @@ class ExamUpdateHandler { } private boolean hasChanges(final Exam exam, final QuizData quizData) { - if (!Objects.equals(exam.name, quizData.name) || + if (!Utils.isEqualsWithEmptyCheck(exam.name, quizData.name) || !Objects.equals(exam.startTime, quizData.startTime) || !Objects.equals(exam.endTime, quizData.endTime) || - !Objects.equals(exam.getDescription(), quizData.description) || - !Objects.equals(exam.getStartURL(), quizData.startURL)) { + !Utils.isEqualsWithEmptyCheck(exam.getDescription(), quizData.description) || + !Utils.isEqualsWithEmptyCheck(exam.getStartURL(), quizData.startURL)) { + + if (log.isDebugEnabled()) { + log.debug("Update difference from LMS. Exam:{}, QuizData: {}", exam, quizData); + } return true; } if (quizData.additionalAttributes != null && !quizData.additionalAttributes.isEmpty()) { for (final Map.Entry attr : quizData.additionalAttributes.entrySet()) { - if (!Objects.equals(exam.getAdditionalAttribute(attr.getKey()), attr.getValue())) { + final String currentAttrValue = exam.getAdditionalAttribute(attr.getKey()); + if (!Utils.isEqualsWithEmptyCheck(currentAttrValue, attr.getValue())) { + if (log.isDebugEnabled()) { + log.debug("Update difference from LMS: attribute{}, currentValue: {}, lmsValue: {}", + attr.getKey(), + currentAttrValue, + attr.getValue()); + } return true; } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ExamProctoringRoomServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ExamProctoringRoomServiceImpl.java index 5241d681..8ddd0d78 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ExamProctoringRoomServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ExamProctoringRoomServiceImpl.java @@ -475,7 +475,8 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService final ExamProctoringService examProctoringService) { // get all connections of the room - final List connectionTokens = this.getActiveCollectingRoomConnections(examId, roomName) + final List connectionTokens = this + .getActiveCollectingRoomConnections(examId, roomName) .getOrThrow() .stream() .map(cc -> cc.connectionToken) @@ -501,6 +502,12 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService connectionTokens, examProctoringService.getDefaultReconfigInstructionAttributes()); } + + // Send the rejoin to collecting room instruction to all involved clients + sendJoinCollectingRoomInstructions( + proctoringSettings, + connectionTokens, + examProctoringService); } private void cleanupBreakOutRooms(final ClientConnectionRecord cc) { diff --git a/src/test/java/ch/ethz/seb/sebserver/gbl/util/ReplTest.java b/src/test/java/ch/ethz/seb/sebserver/gbl/util/ReplTest.java index bd19fe5a..fe39fbce 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gbl/util/ReplTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/gbl/util/ReplTest.java @@ -8,6 +8,13 @@ package ch.ethz.seb.sebserver.gbl.util; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Objects; + +import org.junit.Test; + public class ReplTest { // @Test @@ -48,4 +55,11 @@ public class ReplTest { // assertTrue(new Boolean(false) == new Boolean(false)); // } + @Test + public void testObjectEquals() { + assertTrue(Objects.equals("", "")); + assertTrue(Objects.equals(null, null)); + assertFalse(Objects.equals("", null)); + } + } diff --git a/src/test/java/ch/ethz/seb/sebserver/gbl/util/UtilsTest.java b/src/test/java/ch/ethz/seb/sebserver/gbl/util/UtilsTest.java index 6bc7a523..a5e00fd7 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gbl/util/UtilsTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/gbl/util/UtilsTest.java @@ -243,4 +243,17 @@ public class UtilsTest { .contains("ch.ethz.seb.sebserver.gbl.util.UtilsTest.testFormatStackTracePrint")); } + @Test + public void testIsEqualsWithEmptyCheck() { + assertTrue(Utils.isEqualsWithEmptyCheck("aa", "aa")); + assertTrue(Utils.isEqualsWithEmptyCheck("", "")); + assertTrue(Utils.isEqualsWithEmptyCheck(null, null)); + assertTrue(Utils.isEqualsWithEmptyCheck("", null)); + assertTrue(Utils.isEqualsWithEmptyCheck(null, "")); + assertTrue(Utils.isEqualsWithEmptyCheck(" ", null)); + assertTrue(Utils.isEqualsWithEmptyCheck(" ", " ")); + + assertFalse(Utils.isEqualsWithEmptyCheck(" ", "a")); + } + }