Merge branch 'development' into development_VDI
This commit is contained in:
commit
5440f4bdcd
9 changed files with 101 additions and 38 deletions
|
@ -215,7 +215,9 @@ public class SEBClientEventDetailsPopup {
|
|||
.addField(FormBuilder.text(
|
||||
QuizData.QUIZ_ATTR_DESCRIPTION,
|
||||
FORM_DESC_TEXT_KEY,
|
||||
exam.description))
|
||||
exam.description)
|
||||
.asArea()
|
||||
.asHTML(true))
|
||||
.addField(FormBuilder.text(
|
||||
Domain.EXAM.ATTR_TYPE,
|
||||
FORM_EXAM_TYPE_TEXT_KEY,
|
||||
|
|
|
@ -8,12 +8,31 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
|
||||
|
||||
/** Data access object for webservice info data.
|
||||
* This info is used to verify parallel running webservices and nominate one as master.
|
||||
* It shows also the history of SEB webservice registrations that has not been correctly shot down and still remain in
|
||||
* the persistent data table. */
|
||||
public interface WebserviceInfoDAO {
|
||||
|
||||
/** Register a SEB webservice within the persistent storage
|
||||
*
|
||||
* @param uuid A unique identifier that was generated by the webservice on startup
|
||||
* @param address the IP address of the webservice
|
||||
* @return true if registration was successful */
|
||||
boolean register(String uuid, String address);
|
||||
|
||||
/** This can periodically be called by a specific running webservice to verify whether the webservice is (still) the
|
||||
* master or a slave
|
||||
*
|
||||
* @param uuid The unique identifier of the webservice generated on startup
|
||||
* @return true if the calling webservice is (still) the master service */
|
||||
boolean isMaster(String uuid);
|
||||
|
||||
/** When a webservice has a controlled shout down, it unregister itself within this method.
|
||||
* This removes the data entry of the webservice from persistent storage.
|
||||
*
|
||||
* @param uuid he unique identifier of the webservice generated on startup
|
||||
* @return true when the unregistering was successful */
|
||||
boolean unregister(String uuid);
|
||||
|
||||
}
|
||||
|
|
|
@ -61,25 +61,25 @@ final class MockupLmsAPITemplate implements LmsAPITemplate {
|
|||
final LmsType lmsType = lmsSetup.getLmsType();
|
||||
this.mockups = new ArrayList<>();
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz1", institutionId, lmsSetupId, lmsType, "Demo Quiz 1 (MOCKUP)", "Demo Quiz Mockup",
|
||||
"quiz1", institutionId, lmsSetupId, lmsType, "Demo Quiz 1 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
|
||||
"2020-01-01T09:00:00Z", null, "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz2", institutionId, lmsSetupId, lmsType, "Demo Quiz 2 (MOCKUP)", "Demo Quiz Mockup",
|
||||
"quiz2", institutionId, lmsSetupId, lmsType, "Demo Quiz 2 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
|
||||
"2020-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz3", institutionId, lmsSetupId, lmsType, "Demo Quiz 3 (MOCKUP)", "Demo Quiz Mockup",
|
||||
"quiz3", institutionId, lmsSetupId, lmsType, "Demo Quiz 3 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
|
||||
"2018-07-30T09:00:00Z", "2018-08-01T00:00:00Z", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz4", institutionId, lmsSetupId, lmsType, "Demo Quiz 4 (MOCKUP)", "Demo Quiz Mockup",
|
||||
"quiz4", institutionId, lmsSetupId, lmsType, "Demo Quiz 4 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
|
||||
"2018-01-01T00:00:00Z", "2019-01-01T00:00:00Z", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz5", institutionId, lmsSetupId, lmsType, "Demo Quiz 5 (MOCKUP)", "Demo Quiz Mockup",
|
||||
"quiz5", institutionId, lmsSetupId, lmsType, "Demo Quiz 5 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
|
||||
"2018-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz6", institutionId, lmsSetupId, lmsType, "Demo Quiz 6 (MOCKUP)", "Demo Quiz Mockup",
|
||||
"quiz6", institutionId, lmsSetupId, lmsType, "Demo Quiz 6 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
|
||||
"2019-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/"));
|
||||
this.mockups.add(new QuizData(
|
||||
"quiz7", institutionId, lmsSetupId, lmsType, "Demo Quiz 7 (MOCKUP)", "Demo Quiz Mockup",
|
||||
"quiz7", institutionId, lmsSetupId, lmsType, "Demo Quiz 7 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
|
||||
"2018-01-01T09:00:00Z", "2022-01-01T09:00:00Z", "http://lms.mockup.com/api/"));
|
||||
|
||||
this.mockups.add(new QuizData(
|
||||
|
|
|
@ -14,6 +14,7 @@ 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.model.session.IndicatorValue;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientEventRecord;
|
||||
|
||||
/** A client indicator is a indicator value holder for a specific Indicator
|
||||
* on a running client connection.
|
||||
|
@ -58,4 +59,6 @@ public interface ClientIndicator extends IndicatorValue {
|
|||
* @param event The ClientEvent instance */
|
||||
void notifyValueChange(ClientEvent event);
|
||||
|
||||
void notifyValueChange(ClientEventRecord clientEventRecord);
|
||||
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ class ExamSessionControlTask implements DisposableBean {
|
|||
}
|
||||
|
||||
@Scheduled(fixedRateString = "${sebserver.webservice.api.seb.lostping.update:5000}")
|
||||
public void pingEventUpdateTask() {
|
||||
public void examSessionUpdateTask() {
|
||||
|
||||
if (!this.webserviceInfoDAO.isMaster(this.webserviceInfo.getWebserviceUUID())) {
|
||||
return;
|
||||
|
|
|
@ -31,6 +31,7 @@ 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.model.session.ClientConnectionData;
|
||||
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.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||
|
@ -524,34 +525,39 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
|
|||
final String connectionToken,
|
||||
final ClientEvent event) {
|
||||
|
||||
final ClientConnectionDataInternal activeClientConnection =
|
||||
this.examSessionCacheService.getClientConnection(connectionToken);
|
||||
try {
|
||||
final ClientConnectionDataInternal activeClientConnection =
|
||||
this.examSessionCacheService.getClientConnection(connectionToken);
|
||||
|
||||
if (activeClientConnection != null) {
|
||||
if (activeClientConnection != null) {
|
||||
|
||||
// store event
|
||||
this.eventHandlingStrategy.accept(ClientEvent.toRecord(
|
||||
event,
|
||||
activeClientConnection.getConnectionId()));
|
||||
// store event
|
||||
this.eventHandlingStrategy.accept(ClientEvent.toRecord(
|
||||
event,
|
||||
activeClientConnection.getConnectionId()));
|
||||
|
||||
switch (event.eventType) {
|
||||
case NOTIFICATION: {
|
||||
this.sebClientNotificationService.notifyNewNotification(activeClientConnection.getConnectionId());
|
||||
break;
|
||||
}
|
||||
case NOTIFICATION_CONFIRMED: {
|
||||
this.sebClientNotificationService.confirmPendingNotification(event, connectionToken);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// update indicators
|
||||
activeClientConnection.getIndicatorMapping(event.eventType)
|
||||
.forEach(indicator -> indicator.notifyValueChange(event));
|
||||
switch (event.eventType) {
|
||||
case NOTIFICATION: {
|
||||
this.sebClientNotificationService
|
||||
.notifyNewNotification(activeClientConnection.getConnectionId());
|
||||
break;
|
||||
}
|
||||
case NOTIFICATION_CONFIRMED: {
|
||||
this.sebClientNotificationService.confirmPendingNotification(event, connectionToken);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// update indicators
|
||||
activeClientConnection.getIndicatorMapping(event.eventType)
|
||||
.forEach(indicator -> indicator.notifyValueChange(event));
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
log.warn("No active ClientConnection found for connectionToken: {}", connectionToken);
|
||||
}
|
||||
|
||||
} else {
|
||||
log.warn("No active ClientConnection found for connectionToken: {}", connectionToken);
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to process SEB client event: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -734,6 +740,12 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic
|
|||
this.clientConnectionDAO.save(connection.clientConnection);
|
||||
this.examSessionCacheService.evictClientConnection(
|
||||
connection.clientConnection.connectionToken);
|
||||
} else {
|
||||
// update indicators
|
||||
if (clientEventRecord.getType() != null && EventType.ERROR_LOG.id == clientEventRecord.getType()) {
|
||||
connection.getIndicatorMapping(EventType.ERROR_LOG)
|
||||
.forEach(indicator -> indicator.notifyValueChange(clientEventRecord));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -20,6 +20,7 @@ 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 AbstractLogLevelCountIndicator extends AbstractLogIndicator {
|
||||
|
||||
|
@ -37,9 +38,18 @@ public abstract class AbstractLogLevelCountIndicator extends AbstractLogIndicato
|
|||
|
||||
@Override
|
||||
public void notifyValueChange(final ClientEvent event) {
|
||||
valueChanged(event.text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyValueChange(final ClientEventRecord clientEventRecord) {
|
||||
valueChanged(clientEventRecord.getText());
|
||||
}
|
||||
|
||||
private void valueChanged(final String eventText) {
|
||||
if (this.tags == null || this.tags.length == 0) {
|
||||
this.currentValue = getValue() + 1d;
|
||||
} else if (hasTag(event.text)) {
|
||||
} else if (hasTag(eventText)) {
|
||||
this.currentValue = getValue() + 1d;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,10 +41,22 @@ public abstract class AbstractLogNumberIndicator extends AbstractLogIndicator {
|
|||
|
||||
@Override
|
||||
public void notifyValueChange(final ClientEvent event) {
|
||||
valueChanged(event.text, event.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyValueChange(final ClientEventRecord clientEventRecord) {
|
||||
final BigDecimal numericValue = clientEventRecord.getNumericValue();
|
||||
if (numericValue != null) {
|
||||
valueChanged(clientEventRecord.getText(), numericValue.doubleValue());
|
||||
}
|
||||
}
|
||||
|
||||
private void valueChanged(final String text, final double value) {
|
||||
if (this.tags == null || this.tags.length == 0) {
|
||||
this.currentValue = event.getValue();
|
||||
} else if (hasTag(event.text)) {
|
||||
this.currentValue = event.getValue();
|
||||
this.currentValue = value;
|
||||
} else if (hasTag(text)) {
|
||||
this.currentValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,11 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyValueChange(final ClientEventRecord clientEventRecord) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientEventRecord updateLogEvent(final long now) {
|
||||
final long value = now - (long) super.currentValue;
|
||||
|
|
Loading…
Reference in a new issue