diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java index f7f30c25..01bd18e7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java @@ -63,7 +63,9 @@ public class APIMessage implements Serializable { EXAM_IMPORT_ERROR_AUTO_SETUP("1600", HttpStatus.PARTIAL_CONTENT, "Exam successfully imported but some additional initialization failed"), EXAM_IMPORT_ERROR_AUTO_INDICATOR("1601", HttpStatus.PARTIAL_CONTENT, - "Failed to automatically create pre-defined indicators for the exam"), + "Failed to automatically create pre-defined indicator(s) for the exam"), + EXAM_IMPORT_ERROR_AUTO_CLIENT_GROUPS("1604", HttpStatus.PARTIAL_CONTENT, + "Failed to automatically create pre-defined client group(s) for the exam"), EXAM_IMPORT_ERROR_AUTO_ATTRIBUTES("1602", HttpStatus.PARTIAL_CONTENT, "Failed to automatically create pre-defined attributes for the exam"), EXAM_IMPORT_ERROR_AUTO_RESTRICTION("1603", HttpStatus.PARTIAL_CONTENT, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java index 0c3f4026..1086b3ec 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java @@ -116,8 +116,6 @@ public class WebserviceInit implements ApplicationListener "); SEBServerInit.INIT_LOGGER.info("----> Distributed Setup: {}", this.webserviceInfo.getWebserviceUUID()); - SEBServerInit.INIT_LOGGER.info("----> Ping update time: {}", - this.environment.getProperty("sebserver.webservice.distributed.pingUpdate")); SEBServerInit.INIT_LOGGER.info("----> Connection update time: {}", this.environment.getProperty("sebserver.webservice.distributed.connectionUpdate", "2000")); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java index cd01814b..b806387b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java @@ -15,8 +15,6 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; -import org.springframework.transaction.annotation.Transactional; - import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityDependency; @@ -52,7 +50,6 @@ public interface BulkActionSupportDAO { * * @param bulkAction the BulkAction containing the source entity and all dependencies * @return a Collection of EntityKey results of each Entity that has been processed. */ - @Transactional default Collection> processBulkAction(final BulkAction bulkAction) { final Set all = bulkAction.extractKeys(entityType()); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java index 6d453c87..d6a04570 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java @@ -96,7 +96,6 @@ public class BulkActionServiceImpl implements BulkActionService { } @Override - public Result doBulkAction(final BulkAction action) { return Result.tryCatch(() -> { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java index b22b9e3a..60b4d67f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java @@ -322,7 +322,7 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO { activityType.name(), entityType.name(), entityId, - message)); + Utils.truncateText(message, 4000))); } @Override diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamTemplateServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamTemplateServiceImpl.java index 87b069cd..76d3dc78 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamTemplateServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamTemplateServiceImpl.java @@ -384,7 +384,7 @@ public class ExamTemplateServiceImpl implements ExamTemplateService { } if (log.isDebugEnabled()) { - log.debug("Init default indicator for exam: {}", exam.externalId); + log.debug("Initialized default indicator for exam: {}", exam.externalId); } final Collection thresholds = this.jsonMapper.readValue( 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 37e32ff0..acbecb47 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 @@ -115,7 +115,10 @@ public class MockCourseAccessAPI implements CourseAccessAPI { @Override public LmsSetupTestResult testCourseAccessAPI() { - log.info("Test Lms Binding for Mockup and LmsSetup: {}", this.apiTemplateDataSupplier.getLmsSetup()); + + if (log.isDebugEnabled()) { + log.debug("Test Lms Binding for Mockup and LmsSetup: {}", this.apiTemplateDataSupplier.getLmsSetup()); + } final List missingAttrs = checkAttributes(); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java index f414d798..c6a3ddcd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java @@ -139,16 +139,21 @@ public class ExamSessionCacheService { key = "#connectionToken", unless = "#result == null") public ClientConnectionDataInternal getClientConnection(final String connectionToken) { + try { + if (log.isTraceEnabled()) { + log.trace("Verify ClientConnection for running exam for caching by connectionToken: {}", + connectionToken); + } - if (log.isTraceEnabled()) { - log.trace("Verify ClientConnection for running exam for caching by connectionToken: {}", connectionToken); - } - - final ClientConnection clientConnection = getClientConnectionByToken(connectionToken); - if (clientConnection == null) { + final ClientConnection clientConnection = getClientConnectionByToken(connectionToken); + if (clientConnection == null) { + return null; + } else { + return this.internalClientConnectionDataFactory.createClientConnectionData(clientConnection); + } + } catch (final Exception e) { + log.error("Failed to get client connection: ", e); return null; - } else { - return this.internalClientConnectionDataFactory.createClientConnectionData(clientConnection); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java index df7c165f..8098bf0e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java @@ -38,8 +38,8 @@ import ch.ethz.seb.sebserver.gbl.model.exam.Exam; import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus; -import ch.ethz.seb.sebserver.gbl.monitoring.MonitoringSEBConnectionData; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData; +import ch.ethz.seb.sebserver.gbl.monitoring.MonitoringSEBConnectionData; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientConnectionDAO; @@ -408,20 +408,22 @@ public class ExamSessionServiceImpl implements ExamSessionService { updateClientConnections(examId); - final List filteredConnections = this.clientConnectionDAO - .getConnectionTokens(examId) - .getOrThrow() - .stream() - .map(token -> getConnectionData(token).getOr(null)) - .filter(Objects::nonNull) - .map(c -> { - statusMapping[c.clientConnection.status.code]++; - return c; - }) - .filter(filter) - .collect(Collectors.toList()); + synchronized (this.examSessionCacheService) { + final List filteredConnections = this.clientConnectionDAO + .getConnectionTokens(examId) + .getOrThrow() + .stream() + .map(token -> this.examSessionCacheService.getClientConnection(token)) + .filter(Objects::nonNull) + .map(c -> { + statusMapping[c.clientConnection.status.code]++; + return c; + }) + .filter(filter) + .collect(Collectors.toList()); - return new MonitoringSEBConnectionData(examId, filteredConnections, statusMapping); + return new MonitoringSEBConnectionData(examId, filteredConnections, statusMapping); + } }); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/DistributedIndicatorValueService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/DistributedIndicatorValueService.java index 8e564645..f09906e7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/DistributedIndicatorValueService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/DistributedIndicatorValueService.java @@ -109,6 +109,8 @@ public class DistributedIndicatorValueService implements DisposableBean { SEBServerInit.INIT_LOGGER.info("------> with distributedUpdateInterval: {}", this.distributedUpdateInterval); + SEBServerInit.INIT_LOGGER.info("------> with update tolerance: {}", + this.updateTolerance); SEBServerInit.INIT_LOGGER.info("------> with taskScheduler: {}", taskScheduler); try { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java index a9adc311..47f6c21b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java @@ -393,6 +393,11 @@ public class ExamAdministrationController extends EntityController { errors.add(ErrorMessage.EXAM_IMPORT_ERROR_AUTO_INDICATOR.of(error)); return entity; }) + .flatMap(this.examTemplateService::addDefinedClientGroups) + .onErrorDo(error -> { + errors.add(ErrorMessage.EXAM_IMPORT_ERROR_AUTO_CLIENT_GROUPS.of(error)); + return entity; + }) .flatMap(this.examTemplateService::initAdditionalAttributes) .onErrorDo(error -> { errors.add(ErrorMessage.EXAM_IMPORT_ERROR_AUTO_ATTRIBUTES.of(error)); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 38f5b518..25dcd4b6 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -675,8 +675,8 @@ sebserver.exam.indicator.type.description.WLAN_STATUS=This indicator shows the p sebserver.exam.clientgroup.type.IP_V4_RANGE=IP v4 Range sebserver.exam.clientgroup.type.CLIENT_OS=SEB Client OS sebserver.exam.clientgroup.type.description.NONE=No Client Group type is selected.
Please select one. -sebserver.exam.clientgroup.type.description.IP_V4_RANGE=IP v4 Range TODO -sebserver.exam.clientgroup.type.description.CLIENT_OS=SEB Client OS TODO +sebserver.exam.clientgroup.type.description.IP_V4_RANGE=With IP v4 range groups you can group the SEB client connections within a IP ranges.
Every SEB client that is connected with a given client IP address that is within the
defined range (including start and end address) belongs to this group.
This is mostly useful if you have dedicated managed devices where you know
the IP ranges for e.g. your computer rooms. +sebserver.exam.clientgroup.type.description.CLIENT_OS=With SEB Client groups you can group the SEB client connections within the
operating system they are running on.
For this grouping type there is a defined SEB OS type for each
supported OS; Windows, MacOS and iOS.
This is mostly useful if you want to monitor and manage
the SEB clients by different operating system types to give respective support. sebserver.exam.indicator.info.pleaseSelect=At first please select an indicator from the list diff --git a/src/main/resources/static/images/clientgroup.png b/src/main/resources/static/images/clientgroup.png index 10dee828..827b15ba 100644 Binary files a/src/main/resources/static/images/clientgroup.png and b/src/main/resources/static/images/clientgroup.png differ