Merge branch 'rel-1.4.1'
This commit is contained in:
commit
e704bde073
11 changed files with 91 additions and 31 deletions
2
pom.xml
2
pom.xml
|
@ -18,7 +18,7 @@
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<sebserver-version>1.4.0</sebserver-version>
|
<sebserver-version>1.4.1</sebserver-version>
|
||||||
<build-version>${sebserver-version}</build-version>
|
<build-version>${sebserver-version}</build-version>
|
||||||
<revision>${sebserver-version}</revision>
|
<revision>${sebserver-version}</revision>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -742,14 +742,20 @@ public class ExamDAOImpl implements ExamDAO {
|
||||||
|
|
||||||
private QuizData saveAdditionalQuizAttributes(final Long examId, final QuizData quizData) {
|
private QuizData saveAdditionalQuizAttributes(final Long examId, final QuizData quizData) {
|
||||||
final Map<String, String> additionalAttributes = new HashMap<>(quizData.getAdditionalAttributes());
|
final Map<String, String> additionalAttributes = new HashMap<>(quizData.getAdditionalAttributes());
|
||||||
additionalAttributes.put(QuizData.QUIZ_ATTR_DESCRIPTION, quizData.description);
|
if (StringUtils.isNotBlank(quizData.description)) {
|
||||||
additionalAttributes.put(QuizData.QUIZ_ATTR_START_URL, quizData.startURL);
|
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(
|
if (!additionalAttributes.isEmpty()) {
|
||||||
EntityType.EXAM,
|
this.additionalAttributesDAO.saveAdditionalAttributes(
|
||||||
examId,
|
EntityType.EXAM,
|
||||||
additionalAttributes)
|
examId,
|
||||||
.getOrThrow();
|
additionalAttributes)
|
||||||
|
.getOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
return quizData;
|
return quizData;
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,8 +135,6 @@ public class UserDAOImpl implements UserDAO {
|
||||||
this.userRecordMapper
|
this.userRecordMapper
|
||||||
.selectByExample()
|
.selectByExample()
|
||||||
.where(UserRecordDynamicSqlSupport.username, isEqualTo(username))
|
.where(UserRecordDynamicSqlSupport.username, isEqualTo(username))
|
||||||
.and(UserRecordDynamicSqlSupport.active,
|
|
||||||
isEqualTo(BooleanUtils.toInteger(true)))
|
|
||||||
.build()
|
.build()
|
||||||
.execute())
|
.execute())
|
||||||
.flatMap(this::sebServerUserFromRecord);
|
.flatMap(this::sebServerUserFromRecord);
|
||||||
|
|
|
@ -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.
|
/** 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
|
* 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.
|
* considered to not set on the LMS.
|
||||||
*
|
*
|
||||||
|
|
|
@ -197,6 +197,7 @@ public class SEBRestrictionServiceImpl implements SEBRestrictionService {
|
||||||
log.info("ExamStartedEvent received, process applySEBClientRestriction...");
|
log.info("ExamStartedEvent received, process applySEBClientRestriction...");
|
||||||
|
|
||||||
applySEBClientRestriction(event.exam)
|
applySEBClientRestriction(event.exam)
|
||||||
|
.flatMap(e -> this.examDAO.setSEBRestriction(e.id, true))
|
||||||
.onError(error -> log.error(
|
.onError(error -> log.error(
|
||||||
"Failed to apply SEB restrictions for started exam: {}",
|
"Failed to apply SEB restrictions for started exam: {}",
|
||||||
event.exam,
|
event.exam,
|
||||||
|
|
|
@ -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.ConfigurationDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamConfigurationMapDAO;
|
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.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.ExamConfigUpdateService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
|
||||||
|
|
||||||
|
@ -45,22 +44,19 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
private final ExamConfigurationMapDAO examConfigurationMapDAO;
|
private final ExamConfigurationMapDAO examConfigurationMapDAO;
|
||||||
private final ExamSessionService examSessionService;
|
private final ExamSessionService examSessionService;
|
||||||
private final ExamUpdateHandler examUpdateHandler;
|
private final ExamUpdateHandler examUpdateHandler;
|
||||||
private final ExamAdminService examAdminService;
|
|
||||||
|
|
||||||
protected ExamConfigUpdateServiceImpl(
|
protected ExamConfigUpdateServiceImpl(
|
||||||
final ExamDAO examDAO,
|
final ExamDAO examDAO,
|
||||||
final ConfigurationDAO configurationDAO,
|
final ConfigurationDAO configurationDAO,
|
||||||
final ExamConfigurationMapDAO examConfigurationMapDAO,
|
final ExamConfigurationMapDAO examConfigurationMapDAO,
|
||||||
final ExamSessionService examSessionService,
|
final ExamSessionService examSessionService,
|
||||||
final ExamUpdateHandler examUpdateHandler,
|
final ExamUpdateHandler examUpdateHandler) {
|
||||||
final ExamAdminService examAdminService) {
|
|
||||||
|
|
||||||
this.examDAO = examDAO;
|
this.examDAO = examDAO;
|
||||||
this.configurationDAO = configurationDAO;
|
this.configurationDAO = configurationDAO;
|
||||||
this.examConfigurationMapDAO = examConfigurationMapDAO;
|
this.examConfigurationMapDAO = examConfigurationMapDAO;
|
||||||
this.examSessionService = examSessionService;
|
this.examSessionService = examSessionService;
|
||||||
this.examUpdateHandler = examUpdateHandler;
|
this.examUpdateHandler = examUpdateHandler;
|
||||||
this.examAdminService = examAdminService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// processing:
|
// 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)
|
// 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) {
|
for (final Exam exam : exams) {
|
||||||
if (exam.getStatus() == ExamStatus.RUNNING || this.examAdminService.isRestricted(exam).getOr(false)) {
|
if (exam.getStatus() == ExamStatus.RUNNING) {
|
||||||
|
|
||||||
this.examUpdateHandler
|
this.examUpdateHandler
|
||||||
.getSEBRestrictionService()
|
.getSEBRestrictionService()
|
||||||
.applySEBClientRestriction(exam)
|
.applySEBClientRestriction(exam)
|
||||||
|
.flatMap(e -> this.examDAO.setSEBRestriction(e.id, true))
|
||||||
.onError(t -> log.error("Failed to update SEB Client restriction for Exam: {}", exam, t));
|
.onError(t -> log.error("Failed to update SEB Client restriction for Exam: {}", exam, t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,15 +198,14 @@ public class ExamConfigUpdateServiceImpl implements ExamConfigUpdateService {
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
// update seb client restriction if the feature is activated for the exam
|
// update seb client restriction if the feature is activated for the exam
|
||||||
if (this.examAdminService.isRestricted(exam).getOr(false)) {
|
this.examUpdateHandler
|
||||||
this.examUpdateHandler
|
.getSEBRestrictionService()
|
||||||
.getSEBRestrictionService()
|
.applySEBClientRestriction(exam)
|
||||||
.applySEBClientRestriction(exam)
|
.flatMap(e -> this.examDAO.setSEBRestriction(e.id, true))
|
||||||
.onError(t -> log.error(
|
.onError(t -> log.error(
|
||||||
"Failed to update SEB Client restriction for Exam: {}",
|
"Failed to update SEB Client restriction for Exam: {}",
|
||||||
exam,
|
exam,
|
||||||
t));
|
t));
|
||||||
}
|
|
||||||
|
|
||||||
// flush the exam cache. If there was an error during flush, it is logged but this process goes on
|
// 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
|
// and the saved changes are not rolled back
|
||||||
|
|
|
@ -338,18 +338,29 @@ class ExamUpdateHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasChanges(final Exam exam, final QuizData quizData) {
|
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.startTime, quizData.startTime) ||
|
||||||
!Objects.equals(exam.endTime, quizData.endTime) ||
|
!Objects.equals(exam.endTime, quizData.endTime) ||
|
||||||
!Objects.equals(exam.getDescription(), quizData.description) ||
|
!Utils.isEqualsWithEmptyCheck(exam.getDescription(), quizData.description) ||
|
||||||
!Objects.equals(exam.getStartURL(), quizData.startURL)) {
|
!Utils.isEqualsWithEmptyCheck(exam.getStartURL(), quizData.startURL)) {
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
log.debug("Update difference from LMS. Exam:{}, QuizData: {}", exam, quizData);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quizData.additionalAttributes != null && !quizData.additionalAttributes.isEmpty()) {
|
if (quizData.additionalAttributes != null && !quizData.additionalAttributes.isEmpty()) {
|
||||||
for (final Map.Entry<String, String> attr : quizData.additionalAttributes.entrySet()) {
|
for (final Map.Entry<String, String> 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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -475,7 +475,8 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService
|
||||||
final ExamProctoringService examProctoringService) {
|
final ExamProctoringService examProctoringService) {
|
||||||
|
|
||||||
// get all connections of the room
|
// get all connections of the room
|
||||||
final List<String> connectionTokens = this.getActiveCollectingRoomConnections(examId, roomName)
|
final List<String> connectionTokens = this
|
||||||
|
.getActiveCollectingRoomConnections(examId, roomName)
|
||||||
.getOrThrow()
|
.getOrThrow()
|
||||||
.stream()
|
.stream()
|
||||||
.map(cc -> cc.connectionToken)
|
.map(cc -> cc.connectionToken)
|
||||||
|
@ -501,6 +502,12 @@ public class ExamProctoringRoomServiceImpl implements ExamProctoringRoomService
|
||||||
connectionTokens,
|
connectionTokens,
|
||||||
examProctoringService.getDefaultReconfigInstructionAttributes());
|
examProctoringService.getDefaultReconfigInstructionAttributes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send the rejoin to collecting room instruction to all involved clients
|
||||||
|
sendJoinCollectingRoomInstructions(
|
||||||
|
proctoringSettings,
|
||||||
|
connectionTokens,
|
||||||
|
examProctoringService);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanupBreakOutRooms(final ClientConnectionRecord cc) {
|
private void cleanupBreakOutRooms(final ClientConnectionRecord cc) {
|
||||||
|
|
|
@ -8,6 +8,13 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.util;
|
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 {
|
public class ReplTest {
|
||||||
|
|
||||||
// @Test
|
// @Test
|
||||||
|
@ -48,4 +55,11 @@ public class ReplTest {
|
||||||
// assertTrue(new Boolean(false) == new Boolean(false));
|
// assertTrue(new Boolean(false) == new Boolean(false));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testObjectEquals() {
|
||||||
|
assertTrue(Objects.equals("", ""));
|
||||||
|
assertTrue(Objects.equals(null, null));
|
||||||
|
assertFalse(Objects.equals("", null));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,4 +243,17 @@ public class UtilsTest {
|
||||||
.contains("ch.ethz.seb.sebserver.gbl.util.UtilsTest.testFormatStackTracePrint"));
|
.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"));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue