SEBSERV-136 battary and wlan status indicator impl and tests
This commit is contained in:
parent
7c5a2da59d
commit
448c4d26b5
22 changed files with 478 additions and 154 deletions
|
@ -101,6 +101,9 @@ public final class API {
|
||||||
|
|
||||||
public static final String EXAM_API_EVENT_ENDPOINT = "/seblog";
|
public static final String EXAM_API_EVENT_ENDPOINT = "/seblog";
|
||||||
|
|
||||||
|
public static final String LOG_EVENT_TAG_BATTERY_STATUS = "<battery>";
|
||||||
|
public static final String LOG_EVENT_TAG_WLAN_STATUS = "<wlan>";
|
||||||
|
|
||||||
// *************************
|
// *************************
|
||||||
// ** Domain Object API
|
// ** Domain Object API
|
||||||
// *************************
|
// *************************
|
||||||
|
|
|
@ -35,23 +35,31 @@ public final class Indicator implements Entity {
|
||||||
public static final String FILTER_ATTR_EXAM_ID = "examId";
|
public static final String FILTER_ATTR_EXAM_ID = "examId";
|
||||||
|
|
||||||
public enum IndicatorType {
|
public enum IndicatorType {
|
||||||
LAST_PING(Names.LAST_PING, true, true),
|
LAST_PING(Names.LAST_PING, true, true, false, false),
|
||||||
ERROR_COUNT(Names.ERROR_COUNT, true, false),
|
ERROR_COUNT(Names.ERROR_COUNT, true, false, true, false),
|
||||||
WARN_COUNT(Names.WARN_COUNT, true, false),
|
WARN_COUNT(Names.WARN_COUNT, true, false, true, false),
|
||||||
INFO_COUNT(Names.INFO_COUNT, true, false);
|
INFO_COUNT(Names.INFO_COUNT, true, false, true, false),
|
||||||
|
BATTERY_STATUS(Names.BATTERY_STATUS, true, true, true, true),
|
||||||
|
WLAN_STATUS(Names.WLAN_STATUS, true, true, true, true);
|
||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public final boolean integerValue;
|
public final boolean integerValue;
|
||||||
public final boolean showOnlyInActiveState;
|
public final boolean showOnlyInActiveState;
|
||||||
|
public final boolean tags;
|
||||||
|
public final boolean tagsReadonly;
|
||||||
|
|
||||||
IndicatorType(
|
IndicatorType(
|
||||||
final String name,
|
final String name,
|
||||||
final boolean integerValue,
|
final boolean integerValue,
|
||||||
final boolean showOnlyInActiveState) {
|
final boolean showOnlyInActiveState,
|
||||||
|
final boolean tags,
|
||||||
|
final boolean tagsReadonly) {
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.integerValue = integerValue;
|
this.integerValue = integerValue;
|
||||||
this.showOnlyInActiveState = showOnlyInActiveState;
|
this.showOnlyInActiveState = showOnlyInActiveState;
|
||||||
|
this.tags = tags;
|
||||||
|
this.tagsReadonly = tagsReadonly;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,6 +72,8 @@ public final class Indicator implements Entity {
|
||||||
String ERROR_COUNT = "ERROR_COUNT";
|
String ERROR_COUNT = "ERROR_COUNT";
|
||||||
String WARN_COUNT = "WARN_COUNT";
|
String WARN_COUNT = "WARN_COUNT";
|
||||||
String INFO_COUNT = "INFO_COUNT";
|
String INFO_COUNT = "INFO_COUNT";
|
||||||
|
String BATTERY_STATUS = "BATTERY_STATUS";
|
||||||
|
String WLAN_STATUS = "WLAN_STATUS";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
|
||||||
|
|
||||||
import static org.mybatis.dynamic.sql.SqlBuilder.*;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.mybatis.dynamic.sql.SqlBuilder;
|
|
||||||
import org.mybatis.dynamic.sql.SqlCriterion;
|
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
|
||||||
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.Utils;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordDynamicSqlSupport;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordMapper;
|
|
||||||
|
|
||||||
public abstract class AbstractLogLevelCountIndicator extends AbstractClientIndicator {
|
|
||||||
|
|
||||||
private final Set<EventType> observed;
|
|
||||||
private final List<Integer> eventTypeIds;
|
|
||||||
private final ClientEventRecordMapper clientEventRecordMapper;
|
|
||||||
protected String[] tags;
|
|
||||||
|
|
||||||
protected AbstractLogLevelCountIndicator(
|
|
||||||
final ClientEventRecordMapper clientEventRecordMapper,
|
|
||||||
final EventType... eventTypes) {
|
|
||||||
|
|
||||||
this.clientEventRecordMapper = clientEventRecordMapper;
|
|
||||||
this.observed = Collections.unmodifiableSet(EnumSet.of(eventTypes[0], eventTypes));
|
|
||||||
this.eventTypeIds = Utils.immutableListOf(Arrays.stream(eventTypes)
|
|
||||||
.map(et -> et.id)
|
|
||||||
.collect(Collectors.toList()));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(final Indicator indicatorDefinition, final Long connectionId, final boolean cachingEnabled) {
|
|
||||||
super.init(indicatorDefinition, connectionId, cachingEnabled);
|
|
||||||
if (indicatorDefinition == null || indicatorDefinition.tags == null) {
|
|
||||||
this.tags = null;
|
|
||||||
} else {
|
|
||||||
this.tags = StringUtils.split(indicatorDefinition.tags, Constants.COMMA);
|
|
||||||
for (int i = 0; i < this.tags.length; i++) {
|
|
||||||
this.tags[i] = Constants.ANGLE_BRACE_OPEN + this.tags[i] + Constants.ANGLE_BRACE_CLOSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double computeValueAt(final long timestamp) {
|
|
||||||
|
|
||||||
final Long errors = this.clientEventRecordMapper.countByExample()
|
|
||||||
.where(ClientEventRecordDynamicSqlSupport.clientConnectionId, isEqualTo(this.connectionId))
|
|
||||||
.and(ClientEventRecordDynamicSqlSupport.type, isIn(this.eventTypeIds))
|
|
||||||
.and(ClientEventRecordDynamicSqlSupport.serverTime, isLessThan(timestamp))
|
|
||||||
.and(
|
|
||||||
ClientEventRecordDynamicSqlSupport.text,
|
|
||||||
isLikeWhenPresent(getfirstTagSQL()),
|
|
||||||
getSubTagSQL())
|
|
||||||
.build()
|
|
||||||
.execute();
|
|
||||||
|
|
||||||
return errors.doubleValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getfirstTagSQL() {
|
|
||||||
if (this.tags == null || this.tags.length == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Utils.toSQLWildcard(this.tags[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private SqlCriterion<String>[] getSubTagSQL() {
|
|
||||||
if (this.tags == null || this.tags.length == 0 || this.tags.length == 1) {
|
|
||||||
return new SqlCriterion[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
final SqlCriterion<String>[] result = new SqlCriterion[this.tags.length - 1];
|
|
||||||
for (int i = 1; i < this.tags.length; i++) {
|
|
||||||
result[i - 1] = SqlBuilder.or(
|
|
||||||
ClientEventRecordDynamicSqlSupport.text,
|
|
||||||
isLike(Utils.toSQLWildcard(this.tags[1])));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void notifyValueChange(final ClientEvent event) {
|
|
||||||
if (this.tags == null || this.tags.length == 0) {
|
|
||||||
this.currentValue = getValue() + 1d;
|
|
||||||
} else if (hasTag(event.text)) {
|
|
||||||
this.currentValue = getValue() + 1d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasTag(final String text) {
|
|
||||||
if (text == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < this.tags.length; i++) {
|
|
||||||
if (text.startsWith(this.tags[i])) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<EventType> observedEvents() {
|
|
||||||
return this.observed;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,6 +24,7 @@ import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent.EventType;
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent.EventType;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ClientIndicator;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ClientIndicator;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.PendingNotificationIndication;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.PendingNotificationIndication;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.PingIntervalClientIndicator;
|
||||||
|
|
||||||
public class ClientConnectionDataInternal extends ClientConnectionData {
|
public class ClientConnectionDataInternal extends ClientConnectionData {
|
||||||
|
|
||||||
|
@ -74,7 +75,7 @@ public class ClientConnectionDataInternal extends ClientConnectionData {
|
||||||
@Override
|
@Override
|
||||||
@JsonProperty(ATTR_MISSING_PING)
|
@JsonProperty(ATTR_MISSING_PING)
|
||||||
public Boolean getMissingPing() {
|
public Boolean getMissingPing() {
|
||||||
return this.pingIndicator.missingPing;
|
return this.pingIndicator.isMissingPing();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -28,6 +28,7 @@ import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.IndicatorDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.IndicatorDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ClientIndicator;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ClientIndicator;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.PingIntervalClientIndicator;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
|
@ -93,7 +94,7 @@ public class ClientIndicatorFactory {
|
||||||
if (!pingIndicatorAvailable) {
|
if (!pingIndicatorAvailable) {
|
||||||
final PingIntervalClientIndicator pingIndicator = this.applicationContext
|
final PingIntervalClientIndicator pingIndicator = this.applicationContext
|
||||||
.getBean(PingIntervalClientIndicator.class);
|
.getBean(PingIntervalClientIndicator.class);
|
||||||
pingIndicator.hidden = true;
|
pingIndicator.setHidden();
|
||||||
final Indicator indicator = new Indicator(
|
final Indicator indicator = new Indicator(
|
||||||
null,
|
null,
|
||||||
clientConnection.examId,
|
clientConnection.examId,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.DateTimeZone;
|
import org.joda.time.DateTimeZone;
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent.EventType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
|
|
||||||
|
public abstract class AbstractLogIndicator extends AbstractClientIndicator {
|
||||||
|
|
||||||
|
protected final Set<EventType> observed;
|
||||||
|
protected final List<Integer> eventTypeIds;
|
||||||
|
protected String[] tags;
|
||||||
|
|
||||||
|
protected AbstractLogIndicator(final EventType... eventTypes) {
|
||||||
|
this.observed = Collections.unmodifiableSet(EnumSet.of(eventTypes[0], eventTypes));
|
||||||
|
this.eventTypeIds = Utils.immutableListOf(Arrays.stream(eventTypes)
|
||||||
|
.map(et -> et.id)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(final Indicator indicatorDefinition, final Long connectionId, final boolean cachingEnabled) {
|
||||||
|
super.init(indicatorDefinition, connectionId, cachingEnabled);
|
||||||
|
if (indicatorDefinition == null || indicatorDefinition.tags == null) {
|
||||||
|
this.tags = null;
|
||||||
|
} else {
|
||||||
|
this.tags = StringUtils.split(indicatorDefinition.tags, Constants.COMMA);
|
||||||
|
for (int i = 0; i < this.tags.length; i++) {
|
||||||
|
this.tags[i] = Constants.ANGLE_BRACE_OPEN + this.tags[i] + Constants.ANGLE_BRACE_CLOSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean hasTag(final String text) {
|
||||||
|
if (text == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < this.tags.length; i++) {
|
||||||
|
if (text.startsWith(this.tags[i])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<EventType> observedEvents() {
|
||||||
|
return this.observed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
|
import static org.mybatis.dynamic.sql.SqlBuilder.*;
|
||||||
|
|
||||||
|
import org.mybatis.dynamic.sql.SqlBuilder;
|
||||||
|
import org.mybatis.dynamic.sql.SqlCriterion;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
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.Utils;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordDynamicSqlSupport;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordMapper;
|
||||||
|
|
||||||
|
public abstract class AbstractLogLevelCountIndicator extends AbstractLogIndicator {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AbstractLogLevelCountIndicator.class);
|
||||||
|
|
||||||
|
protected final ClientEventRecordMapper clientEventRecordMapper;
|
||||||
|
|
||||||
|
protected AbstractLogLevelCountIndicator(
|
||||||
|
final ClientEventRecordMapper clientEventRecordMapper,
|
||||||
|
final EventType... eventTypes) {
|
||||||
|
|
||||||
|
super(eventTypes);
|
||||||
|
this.clientEventRecordMapper = clientEventRecordMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyValueChange(final ClientEvent event) {
|
||||||
|
if (this.tags == null || this.tags.length == 0) {
|
||||||
|
this.currentValue = getValue() + 1d;
|
||||||
|
} else if (hasTag(event.text)) {
|
||||||
|
this.currentValue = getValue() + 1d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double computeValueAt(final long timestamp) {
|
||||||
|
try {
|
||||||
|
final Long errors = this.clientEventRecordMapper.countByExample()
|
||||||
|
.where(ClientEventRecordDynamicSqlSupport.clientConnectionId, isEqualTo(this.connectionId))
|
||||||
|
.and(ClientEventRecordDynamicSqlSupport.type, isIn(this.eventTypeIds))
|
||||||
|
.and(ClientEventRecordDynamicSqlSupport.serverTime, isLessThan(timestamp))
|
||||||
|
.and(
|
||||||
|
ClientEventRecordDynamicSqlSupport.text,
|
||||||
|
isLikeWhenPresent(getfirstTagSQL()),
|
||||||
|
getSubTagSQL())
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
return errors.doubleValue();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to get indicator count from persistent storage: ", e);
|
||||||
|
return this.currentValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getfirstTagSQL() {
|
||||||
|
if (this.tags == null || this.tags.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils.toSQLWildcard(this.tags[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private SqlCriterion<String>[] getSubTagSQL() {
|
||||||
|
if (this.tags == null || this.tags.length == 0 || this.tags.length == 1) {
|
||||||
|
return new SqlCriterion[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
final SqlCriterion<String>[] result = new SqlCriterion[this.tags.length - 1];
|
||||||
|
for (int i = 1; i < this.tags.length; i++) {
|
||||||
|
result[i - 1] = SqlBuilder.or(
|
||||||
|
ClientEventRecordDynamicSqlSupport.text,
|
||||||
|
isLike(Utils.toSQLWildcard(this.tags[1])));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
|
import static org.mybatis.dynamic.sql.SqlBuilder.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.mybatis.dynamic.sql.SqlBuilder;
|
||||||
|
import org.mybatis.dynamic.sql.SqlCriterion;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
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.Utils;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordDynamicSqlSupport;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordMapper;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientEventRecord;
|
||||||
|
|
||||||
|
public abstract class AbstractLogNumberIndicator extends AbstractLogIndicator {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AbstractLogNumberIndicator.class);
|
||||||
|
|
||||||
|
protected final ClientEventRecordMapper clientEventRecordMapper;
|
||||||
|
|
||||||
|
protected AbstractLogNumberIndicator(
|
||||||
|
final ClientEventRecordMapper clientEventRecordMapper,
|
||||||
|
final EventType... eventTypes) {
|
||||||
|
|
||||||
|
super(eventTypes);
|
||||||
|
this.clientEventRecordMapper = clientEventRecordMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyValueChange(final ClientEvent event) {
|
||||||
|
if (this.tags == null || this.tags.length == 0) {
|
||||||
|
this.currentValue = event.getValue();
|
||||||
|
} else if (hasTag(event.text)) {
|
||||||
|
this.currentValue = event.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double computeValueAt(final long timestamp) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final List<ClientEventRecord> execute = this.clientEventRecordMapper.selectByExample()
|
||||||
|
.where(ClientEventRecordDynamicSqlSupport.clientConnectionId, isEqualTo(this.connectionId))
|
||||||
|
.and(ClientEventRecordDynamicSqlSupport.type, isIn(this.eventTypeIds))
|
||||||
|
.and(ClientEventRecordDynamicSqlSupport.serverTime, isLessThan(timestamp))
|
||||||
|
.and(
|
||||||
|
ClientEventRecordDynamicSqlSupport.text,
|
||||||
|
isLikeWhenPresent(getfirstTagSQL()),
|
||||||
|
getSubTagSQL())
|
||||||
|
.orderBy(ClientEventRecordDynamicSqlSupport.serverTime.descending())
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
return execute.get(execute.size() - 1).getNumericValue().doubleValue();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to get indicator number from persistent storage: ", e);
|
||||||
|
return this.currentValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getfirstTagSQL() {
|
||||||
|
if (this.tags == null || this.tags.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Utils.toSQLWildcard(this.tags[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private SqlCriterion<String>[] getSubTagSQL() {
|
||||||
|
if (this.tags == null || this.tags.length == 0 || this.tags.length == 1) {
|
||||||
|
return new SqlCriterion[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
final SqlCriterion<String>[] result = new SqlCriterion[this.tags.length - 1];
|
||||||
|
for (int i = 1; i < this.tags.length; i++) {
|
||||||
|
result[i - 1] = SqlBuilder.or(
|
||||||
|
ClientEventRecordDynamicSqlSupport.text,
|
||||||
|
isLike(Utils.toSQLWildcard(this.tags[1])));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
|
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
|
||||||
import static org.mybatis.dynamic.sql.SqlBuilder.isLessThan;
|
import static org.mybatis.dynamic.sql.SqlBuilder.isLessThan;
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent.EventType;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordMapper;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component(IndicatorType.Names.BATTERY_STATUS)
|
||||||
|
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class BatteryStatusIndicator extends AbstractLogNumberIndicator {
|
||||||
|
|
||||||
|
protected BatteryStatusIndicator(final ClientEventRecordMapper clientEventRecordMapper) {
|
||||||
|
super(clientEventRecordMapper, EventType.INFO_LOG);
|
||||||
|
super.tags = new String[] { API.LOG_EVENT_TAG_BATTERY_STATUS };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IndicatorType getType() {
|
||||||
|
return IndicatorType.BATTERY_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -20,6 +20,8 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
||||||
|
@ -62,6 +64,21 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public final boolean isMissingPing() {
|
||||||
|
return this.missingPing;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public final boolean isHidden() {
|
||||||
|
return this.hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public final void setHidden() {
|
||||||
|
this.hidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IndicatorType getType() {
|
public IndicatorType getType() {
|
||||||
return IndicatorType.LAST_PING;
|
return IndicatorType.LAST_PING;
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent.EventType;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordMapper;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component(IndicatorType.Names.WLAN_STATUS)
|
||||||
|
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class WLANStatusIndicator extends AbstractLogNumberIndicator {
|
||||||
|
|
||||||
|
protected WLANStatusIndicator(final ClientEventRecordMapper clientEventRecordMapper) {
|
||||||
|
super(clientEventRecordMapper, EventType.INFO_LOG);
|
||||||
|
super.tags = new String[] { API.LOG_EVENT_TAG_WLAN_STATUS };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IndicatorType getType() {
|
||||||
|
return IndicatorType.WLAN_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
|
@ -916,6 +916,10 @@ public class UserAPITest extends AdministrationAPIIntegrationTester {
|
||||||
.header("Authorization", "Bearer " + examAdminToken))
|
.header("Authorization", "Bearer " + examAdminToken))
|
||||||
.andExpect(status().isForbidden());
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
if ("0".equals(timeNow)) {
|
||||||
|
System.out.println("******");
|
||||||
|
}
|
||||||
|
|
||||||
// With SEB Administrator it should work
|
// With SEB Administrator it should work
|
||||||
final String sebAdminToken = getSebAdminAccess();
|
final String sebAdminToken = getSebAdminAccess();
|
||||||
final EntityProcessingReport report = this.jsonMapper.readValue(
|
final EntityProcessingReport report = this.jsonMapper.readValue(
|
||||||
|
|
|
@ -36,9 +36,9 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecord
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordMapper;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordMapper;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientConnectionRecord;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientConnectionRecord;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientEventRecord;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientEventRecord;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.AbstractPingIndicator;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ClientConnectionDataInternal;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ClientConnectionDataInternal;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ExamSessionCacheService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ExamSessionCacheService;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.AbstractPingIndicator;
|
||||||
|
|
||||||
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
|
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
|
||||||
public class SebConnectionTest extends ExamAPIIntegrationTester {
|
public class SebConnectionTest extends ExamAPIIntegrationTester {
|
||||||
|
|
|
@ -29,7 +29,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientConnectionDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientEventDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientEventDAO;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientConnectionService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientConnectionService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.AbstractLogLevelCountIndicator;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.AbstractLogIndicator;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.AbstractLogLevelCountIndicator;
|
||||||
|
|
||||||
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
|
@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql", "classpath:data-test-additional.sql" })
|
||||||
public class ClientEventServiceTest extends AdministrationAPIIntegrationTester {
|
public class ClientEventServiceTest extends AdministrationAPIIntegrationTester {
|
||||||
|
@ -160,4 +161,55 @@ public class ClientEventServiceTest extends AdministrationAPIIntegrationTester {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBatteryStatusIndicator() {
|
||||||
|
|
||||||
|
final ClientConnection connection = this.clientConnectionDAO
|
||||||
|
.createNew(new ClientConnection(null, 1L, 2L, ConnectionStatus.ACTIVE, "token3", "userId", "", "", 1L,
|
||||||
|
null, false))
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
|
assertNotNull(connection.id);
|
||||||
|
|
||||||
|
final ClientConnectionData connectionData =
|
||||||
|
this.sebClientConnectionService.getExamSessionService().getConnectionData("token3")
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
|
assertNotNull(connectionData);
|
||||||
|
final Optional<? extends IndicatorValue> findFirst = connectionData.indicatorValues
|
||||||
|
.stream()
|
||||||
|
.filter(indicator -> indicator.getType() == IndicatorType.BATTERY_STATUS)
|
||||||
|
.findFirst();
|
||||||
|
assertTrue(findFirst.isPresent());
|
||||||
|
final IndicatorValue clientIndicator = findFirst.get();
|
||||||
|
|
||||||
|
assertEquals("0", IndicatorValue.getDisplayValue(clientIndicator));
|
||||||
|
|
||||||
|
this.sebClientConnectionService.notifyClientEvent(
|
||||||
|
"token3",
|
||||||
|
new ClientEvent(null, connection.id, EventType.INFO_LOG, 1L, 1L, 1.0, "some info other"));
|
||||||
|
|
||||||
|
this.sebClientConnectionService.notifyClientEvent(
|
||||||
|
"token3",
|
||||||
|
new ClientEvent(null, connection.id, EventType.INFO_LOG, 1L, 1L, 1.0, "<vip> some info other"));
|
||||||
|
|
||||||
|
assertEquals("0", IndicatorValue.getDisplayValue(clientIndicator));
|
||||||
|
|
||||||
|
this.sebClientConnectionService.notifyClientEvent(
|
||||||
|
"token3",
|
||||||
|
new ClientEvent(null, connection.id, EventType.INFO_LOG, 1L, 1L, 90.0, "<battery> some info other"));
|
||||||
|
|
||||||
|
assertEquals("90", IndicatorValue.getDisplayValue(clientIndicator));
|
||||||
|
|
||||||
|
this.sebClientConnectionService.notifyClientEvent(
|
||||||
|
"token3",
|
||||||
|
new ClientEvent(null, connection.id, EventType.INFO_LOG, 1L, 1L, 40.0, "<battery> some info other"));
|
||||||
|
|
||||||
|
assertEquals("40", IndicatorValue.getDisplayValue(clientIndicator));
|
||||||
|
|
||||||
|
// test reset indicator value and load it from persistent storage
|
||||||
|
((AbstractLogIndicator) clientIndicator).reset();
|
||||||
|
assertEquals("40", IndicatorValue.getDisplayValue(clientIndicator));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||||
|
|
||||||
|
public class IndicatorValueJSONTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJSONForExtendedIndicatorValue() throws JsonProcessingException {
|
||||||
|
final JSONMapper jsonMapper = new JSONMapper();
|
||||||
|
final ErrorLogCountClientIndicator indicator = new ErrorLogCountClientIndicator(null);
|
||||||
|
final String json = jsonMapper.writeValueAsString(indicator);
|
||||||
|
assertEquals("{\"indicatorType\":\"ERROR_COUNT\",\"indicatorValue\":\"NaN\"}", json);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,11 +6,12 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import org.joda.time.DateTimeUtils;
|
import org.joda.time.DateTimeUtils;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
@ -21,10 +22,15 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.ClientEventExtensionMapp
|
||||||
|
|
||||||
public class PingIntervalClientIndicatorTest {
|
public class PingIntervalClientIndicatorTest {
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanup() {
|
||||||
|
DateTimeUtils.setCurrentMillisProvider(DateTimeUtils.SYSTEM_MILLIS_PROVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreation() {
|
public void testCreation() {
|
||||||
|
|
||||||
DateTimeUtils.setCurrentMillisFixed(1);
|
DateTimeUtils.setCurrentMillisProvider(() -> 1L);
|
||||||
|
|
||||||
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
||||||
|
|
||||||
|
@ -35,7 +41,8 @@ public class PingIntervalClientIndicatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInterval() {
|
public void testInterval() {
|
||||||
DateTimeUtils.setCurrentMillisFixed(1);
|
|
||||||
|
DateTimeUtils.setCurrentMillisProvider(() -> 1L);
|
||||||
|
|
||||||
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
||||||
|
|
||||||
|
@ -43,14 +50,14 @@ public class PingIntervalClientIndicatorTest {
|
||||||
new PingIntervalClientIndicator(clientEventExtensionMapper);
|
new PingIntervalClientIndicator(clientEventExtensionMapper);
|
||||||
assertEquals("0.0", String.valueOf(pingIntervalClientIndicator.getValue()));
|
assertEquals("0.0", String.valueOf(pingIntervalClientIndicator.getValue()));
|
||||||
|
|
||||||
DateTimeUtils.setCurrentMillisFixed(10);
|
DateTimeUtils.setCurrentMillisProvider(() -> 10L);
|
||||||
|
|
||||||
assertEquals("9.0", String.valueOf(pingIntervalClientIndicator.getValue()));
|
assertEquals("9.0", String.valueOf(pingIntervalClientIndicator.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSerialization() throws JsonProcessingException {
|
public void testSerialization() throws JsonProcessingException {
|
||||||
DateTimeUtils.setCurrentMillisFixed(1);
|
DateTimeUtils.setCurrentMillisProvider(() -> 1L);
|
||||||
|
|
||||||
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
||||||
|
|
|
@ -14,7 +14,8 @@ INSERT IGNORE INTO exam VALUES
|
||||||
INSERT IGNORE INTO indicator VALUES
|
INSERT IGNORE INTO indicator VALUES
|
||||||
(1, 2, 'LAST_PING', 'Ping', 'dcdcdc', null, null),
|
(1, 2, 'LAST_PING', 'Ping', 'dcdcdc', null, null),
|
||||||
(2, 2, 'ERROR_COUNT', 'errors', 'dcdcdc', null, null),
|
(2, 2, 'ERROR_COUNT', 'errors', 'dcdcdc', null, null),
|
||||||
(3, 2, 'INFO_COUNT', 'errors <vip,top>', 'dcdcdc', null, 'vip,top')
|
(3, 2, 'INFO_COUNT', 'errors <vip,top>', 'dcdcdc', null, 'vip,top'),
|
||||||
|
(4, 2, 'BATTERY_STATUS', 'battery status', 'dcdcdc', null, 'battery')
|
||||||
;
|
;
|
||||||
|
|
||||||
INSERT IGNORE INTO threshold VALUES
|
INSERT IGNORE INTO threshold VALUES
|
||||||
|
|
Loading…
Add table
Reference in a new issue