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 LOG_EVENT_TAG_BATTERY_STATUS = "<battery>";
|
||||
public static final String LOG_EVENT_TAG_WLAN_STATUS = "<wlan>";
|
||||
|
||||
// *************************
|
||||
// ** Domain Object API
|
||||
// *************************
|
||||
|
|
|
@ -35,23 +35,31 @@ public final class Indicator implements Entity {
|
|||
public static final String FILTER_ATTR_EXAM_ID = "examId";
|
||||
|
||||
public enum IndicatorType {
|
||||
LAST_PING(Names.LAST_PING, true, true),
|
||||
ERROR_COUNT(Names.ERROR_COUNT, true, false),
|
||||
WARN_COUNT(Names.WARN_COUNT, true, false),
|
||||
INFO_COUNT(Names.INFO_COUNT, true, false);
|
||||
LAST_PING(Names.LAST_PING, true, true, false, false),
|
||||
ERROR_COUNT(Names.ERROR_COUNT, true, false, true, false),
|
||||
WARN_COUNT(Names.WARN_COUNT, true, false, 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 boolean integerValue;
|
||||
public final boolean showOnlyInActiveState;
|
||||
public final boolean tags;
|
||||
public final boolean tagsReadonly;
|
||||
|
||||
IndicatorType(
|
||||
final String name,
|
||||
final boolean integerValue,
|
||||
final boolean showOnlyInActiveState) {
|
||||
final boolean showOnlyInActiveState,
|
||||
final boolean tags,
|
||||
final boolean tagsReadonly) {
|
||||
|
||||
this.name = name;
|
||||
this.integerValue = integerValue;
|
||||
this.showOnlyInActiveState = showOnlyInActiveState;
|
||||
this.tags = tags;
|
||||
this.tagsReadonly = tagsReadonly;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,6 +72,8 @@ public final class Indicator implements Entity {
|
|||
String ERROR_COUNT = "ERROR_COUNT";
|
||||
String WARN_COUNT = "WARN_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.webservice.servicelayer.session.ClientIndicator;
|
||||
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 {
|
||||
|
||||
|
@ -74,7 +75,7 @@ public class ClientConnectionDataInternal extends ClientConnectionData {
|
|||
@Override
|
||||
@JsonProperty(ATTR_MISSING_PING)
|
||||
public Boolean getMissingPing() {
|
||||
return this.pingIndicator.missingPing;
|
||||
return this.pingIndicator.isMissingPing();
|
||||
}
|
||||
|
||||
@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.webservice.servicelayer.dao.IndicatorDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ClientIndicator;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicator.PingIntervalClientIndicator;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
|
@ -93,7 +94,7 @@ public class ClientIndicatorFactory {
|
|||
if (!pingIndicatorAvailable) {
|
||||
final PingIntervalClientIndicator pingIndicator = this.applicationContext
|
||||
.getBean(PingIntervalClientIndicator.class);
|
||||
pingIndicator.hidden = true;
|
||||
pingIndicator.setHidden();
|
||||
final Indicator indicator = new Indicator(
|
||||
null,
|
||||
clientConnection.examId,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* 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.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/.
|
||||
*/
|
||||
|
||||
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.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/.
|
||||
*/
|
||||
|
||||
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.context.annotation.Lazy;
|
|
@ -6,7 +6,7 @@
|
|||
* 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.context.annotation.Lazy;
|
|
@ -6,7 +6,7 @@
|
|||
* 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.util.Comparator;
|
||||
|
@ -20,6 +20,8 @@ import org.springframework.context.annotation.Lazy;
|
|||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
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.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
|
||||
public IndicatorType getType() {
|
||||
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/.
|
||||
*/
|
||||
|
||||
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.context.annotation.Lazy;
|
|
@ -916,6 +916,10 @@ public class UserAPITest extends AdministrationAPIIntegrationTester {
|
|||
.header("Authorization", "Bearer " + examAdminToken))
|
||||
.andExpect(status().isForbidden());
|
||||
|
||||
if ("0".equals(timeNow)) {
|
||||
System.out.println("******");
|
||||
}
|
||||
|
||||
// With SEB Administrator it should work
|
||||
final String sebAdminToken = getSebAdminAccess();
|
||||
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.model.ClientConnectionRecord;
|
||||
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.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" })
|
||||
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.FilterMap;
|
||||
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" })
|
||||
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/.
|
||||
*/
|
||||
|
||||
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 org.joda.time.DateTimeUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
|
@ -21,10 +22,15 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.ClientEventExtensionMapp
|
|||
|
||||
public class PingIntervalClientIndicatorTest {
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
DateTimeUtils.setCurrentMillisProvider(DateTimeUtils.SYSTEM_MILLIS_PROVIDER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreation() {
|
||||
|
||||
DateTimeUtils.setCurrentMillisFixed(1);
|
||||
DateTimeUtils.setCurrentMillisProvider(() -> 1L);
|
||||
|
||||
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
||||
|
||||
|
@ -35,7 +41,8 @@ public class PingIntervalClientIndicatorTest {
|
|||
|
||||
@Test
|
||||
public void testInterval() {
|
||||
DateTimeUtils.setCurrentMillisFixed(1);
|
||||
|
||||
DateTimeUtils.setCurrentMillisProvider(() -> 1L);
|
||||
|
||||
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
||||
|
||||
|
@ -43,14 +50,14 @@ public class PingIntervalClientIndicatorTest {
|
|||
new PingIntervalClientIndicator(clientEventExtensionMapper);
|
||||
assertEquals("0.0", String.valueOf(pingIntervalClientIndicator.getValue()));
|
||||
|
||||
DateTimeUtils.setCurrentMillisFixed(10);
|
||||
DateTimeUtils.setCurrentMillisProvider(() -> 10L);
|
||||
|
||||
assertEquals("9.0", String.valueOf(pingIntervalClientIndicator.getValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialization() throws JsonProcessingException {
|
||||
DateTimeUtils.setCurrentMillisFixed(1);
|
||||
DateTimeUtils.setCurrentMillisProvider(() -> 1L);
|
||||
|
||||
final ClientEventExtensionMapper clientEventExtensionMapper = Mockito.mock(ClientEventExtensionMapper.class);
|
||||
|
|
@ -14,7 +14,8 @@ INSERT IGNORE INTO exam VALUES
|
|||
INSERT IGNORE INTO indicator VALUES
|
||||
(1, 2, 'LAST_PING', 'Ping', '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
|
||||
|
|
Loading…
Add table
Reference in a new issue