diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/batis/ClientEventLastPingMapper.java b/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/batis/ClientEventLastPingMapper.java index ff1615c0..cf233e83 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/batis/ClientEventLastPingMapper.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/datalayer/batis/ClientEventLastPingMapper.java @@ -33,7 +33,7 @@ public interface ClientEventLastPingMapper { @SelectProvider(type = SqlProviderAdapter.class, method = "select") @ResultType(ClientEventLastPingRecord.class) @ConstructorArgs({ - @Arg(column = "client_connection_id", javaType = Long.class, jdbcType = JdbcType.BIGINT), + @Arg(column = "id", javaType = Long.class, jdbcType = JdbcType.BIGINT), @Arg(column = "server_time", javaType = Long.class, jdbcType = JdbcType.BIGINT), }) Collection selectMany(SelectStatementProvider select); @@ -42,7 +42,7 @@ public interface ClientEventLastPingMapper { return SelectDSL.selectWithMapper( this::selectMany, - ClientEventRecordDynamicSqlSupport.clientConnectionId.as("client_connection_id"), + ClientEventRecordDynamicSqlSupport.clientConnectionId.as("id"), ClientEventRecordDynamicSqlSupport.serverTime.as("server_time")) .from(ClientEventRecordDynamicSqlSupport.clientEventRecord); @@ -50,14 +50,14 @@ public interface ClientEventLastPingMapper { final class ClientEventLastPingRecord { - public final Long connectionId; + public final Long id; public final Long lastPingTime; public ClientEventLastPingRecord( - final Long client_connection_id, + final Long id, final Long server_time) { - this.connectionId = client_connection_id; + this.id = id; this.lastPingTime = server_time; } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientEventDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientEventDAOImpl.java index 7d3b069d..1d07897b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientEventDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientEventDAOImpl.java @@ -14,7 +14,6 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Objects; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -296,20 +295,38 @@ public class ClientEventDAOImpl implements ClientEventDAO { @Transactional public Result> delete(final Set all) { return Result.tryCatch(() -> { - return all + + final List pks = all .stream() .map(EntityKey::getModelId) .map(Long::parseLong) - .map(pk -> { - final int deleted = this.clientEventRecordMapper.deleteByPrimaryKey(pk); - if (deleted == 1) { - return new EntityKey(String.valueOf(pk), EntityType.CLIENT_EVENT); - } else { - return null; - } - }) - .filter(Objects::nonNull) .collect(Collectors.toList()); + + this.clientEventRecordMapper + .deleteByExample() + .where(ClientEventRecordDynamicSqlSupport.id, isIn(pks)) + .build() + .execute(); + + return pks + .stream() + .map(pk -> new EntityKey(String.valueOf(pk), EntityType.CLIENT_EVENT)) + .collect(Collectors.toList()); + +// return all +// .stream() +// .map(EntityKey::getModelId) +// .map(Long::parseLong) +// .map(pk -> { +// final int deleted = this.clientEventRecordMapper.deleteByPrimaryKey(pk); +// if (deleted == 1) { +// return new EntityKey(String.valueOf(pk), EntityType.CLIENT_EVENT); +// } else { +// return null; +// } +// }) +// .filter(Objects::nonNull) +// .collect(Collectors.toList()); }); } @@ -368,7 +385,7 @@ public class ClientEventDAOImpl implements ClientEventDAO { public Result getLastPing(final Long pk) { return Result.tryCatch(() -> this.clientEventRecordMapper .selectByPrimaryKey(pk) - .getClientTime()); + .getServerTime()); } private Result recordById(final Long id) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ClientConnectionDataInternal.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ClientConnectionDataInternal.java index 4506f0bc..894e99cd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ClientConnectionDataInternal.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ClientConnectionDataInternal.java @@ -75,7 +75,7 @@ public class ClientConnectionDataInternal extends ClientConnectionData { @Override @JsonProperty(ATTR_MISSING_PING) public Boolean getMissingPing() { - return this.pingIndicator.isMissingPing(); + return this.pingIndicator != null && this.pingIndicator.isMissingPing(); } @Override diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java index d7b018cc..c996e4a0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java @@ -512,6 +512,7 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic final Cache cache = this.cacheManager.getCache(ExamSessionCacheService.CACHE_NAME_ACTIVE_CLIENT_CONNECTION); final long now = Utils.getMillisecondsNow(); + final Consumer missingPingUpdate = missingPingUpdate(now); this.examSessionService .getExamDAO() .allRunningExamIds() @@ -529,8 +530,8 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic .map(token -> cache.get(token, ClientConnectionDataInternal.class)) .filter(Objects::nonNull) .filter(connection -> connection.pingIndicator != null && - connection.clientConnection.status.establishedStatus) - .forEach(missingPingUpdate(now)); + connection.clientConnection.status.clientActiveStatus) + .forEach(connection -> missingPingUpdate.accept(connection)); } catch (final Exception e) { log.error("Failed to update ping events: ", e); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractClientIndicator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractClientIndicator.java index bf01df3e..db1d2301 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractClientIndicator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractClientIndicator.java @@ -8,9 +8,10 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator; +import org.joda.time.DateTimeUtils; + import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.model.exam.Indicator; -import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.webservice.servicelayer.session.ClientIndicator; public abstract class AbstractClientIndicator implements ClientIndicator { @@ -63,15 +64,14 @@ public abstract class AbstractClientIndicator implements ClientIndicator { @Override public double getValue() { + final long now = DateTimeUtils.currentTimeMillis(); if (!this.valueInitializes) { - final long now = Utils.getMillisecondsNow(); this.currentValue = computeValueAt(now); this.lastPersistentUpdate = now; this.valueInitializes = true; } if (!this.cachingEnabled && this.active) { - final long now = System.currentTimeMillis(); if (now - this.lastPersistentUpdate > PERSISTENT_UPDATE_INTERVAL) { this.currentValue = computeValueAt(now); this.lastPersistentUpdate = now; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractPingIndicator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractPingIndicator.java index d0419be5..18a5bff0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractPingIndicator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/AbstractPingIndicator.java @@ -13,6 +13,7 @@ import java.util.EnumSet; import java.util.Set; import org.joda.time.DateTime; +import org.joda.time.DateTimeUtils; import org.joda.time.DateTimeZone; import ch.ethz.seb.sebserver.gbl.Constants; @@ -61,7 +62,7 @@ public abstract class AbstractPingIndicator extends AbstractClientIndicator { if (!this.cachingEnabled && this.pingRecord != null) { // Update last ping time on persistent storage - final long millisecondsNow = System.currentTimeMillis(); + final long millisecondsNow = DateTimeUtils.currentTimeMillis(); if (millisecondsNow - this.lastUpdate > INTERVAL_FOR_PERSISTENT_UPDATE) { this.pingRecord.setClientTime(timestamp); this.pingRecord.setServerTime(millisecondsNow); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/PingIntervalClientIndicator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/PingIntervalClientIndicator.java index 2ce20a79..c4954a74 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/PingIntervalClientIndicator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/indicator/PingIntervalClientIndicator.java @@ -11,8 +11,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator; import java.math.BigDecimal; import java.util.Comparator; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; +import org.joda.time.DateTimeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -28,7 +27,6 @@ import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType; import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent; import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent.EventType; import ch.ethz.seb.sebserver.gbl.util.Result; -import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientEventRecord; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientEventDAO; @@ -51,7 +49,6 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator { public PingIntervalClientIndicator(final ClientEventDAO clientEventDAO) { super(clientEventDAO); this.cachingEnabled = true; - this.currentValue = computeValueAt(Utils.getMillisecondsNow()); } @Override @@ -63,6 +60,8 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator { super.init(indicatorDefinition, connectionId, active, cachingEnabled); + this.currentValue = computeValueAt(DateTimeUtils.currentTimeMillis()); + try { indicatorDefinition .getThresholds() @@ -77,7 +76,8 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator { if (!cachingEnabled) { try { - this.missingPing = this.pingErrorThreshold < getValue(); + final double value = getValue(); + this.missingPing = this.pingErrorThreshold < value; } catch (final Exception e) { log.error("Failed to initialize missingPing: {}", e.getMessage()); this.missingPing = false; @@ -108,7 +108,7 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator { @Override public double getValue() { - final long now = DateTime.now(DateTimeZone.UTC).getMillis(); + final long now = DateTimeUtils.currentTimeMillis(); return now - super.getValue(); } @@ -134,6 +134,9 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator { .getLastPing(super.pingRecord.getId()); if (!lastPing.hasError()) { + if (Double.isNaN(this.currentValue)) { + return lastPing.get().doubleValue(); + } return Math.max(this.currentValue, lastPing.get().doubleValue()); } else { log.error("Failed to get last ping from persistent: {}", lastPing.getError().getMessage()); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 71f7206d..99e790a8 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -596,7 +596,7 @@ sebserver.exam.indicator.type.WLAN_STATUS=WiFi Status sebserver.exam.indicator.type.description.LAST_PING=This indicator shows the time in milliseconds since
the last ping has been received from a SEB Client.
This indicator can be used to track a SEB Client connection and indicate connection loss.

The value is in milliseconds. sebserver.exam.indicator.type.description.ERROR_COUNT=This indicator shows the number of error log messages that
has been received from a SEB Client.
This indicator can be used to track errors of connected SEB Clients

The value is a natural number. sebserver.exam.indicator.type.description.WARN_COUNT=This indicator shows the number of warn log messages that
has been received from a SEB Client.
This indicator can be used to track warnings of connected SEB Clients

The value is a natural number. -sebserver.exam.indicator.type.description.INFO_COUNT=This indicator shows the number of warn log messages that
has been received from a SEB Client.
This indicator can be used to track warnings of connected SEB Clients

The value is a natural number. +sebserver.exam.indicator.type.description.INFO_COUNT=This indicator shows the number of info log messages that
has been received from a SEB Client.
This indicator can be used to track warnings of connected SEB Clients

The value is a natural number. sebserver.exam.indicator.type.description.BATTERY_STATUS=This indicator shows the percentage of the battery load level of a SEB Client. sebserver.exam.indicator.type.description.WLAN_STATUS=This indicator shows the percentage of the WiFi connection status of a SEB Client.