active client connection handling and find-bugs

This commit is contained in:
anhefti 2019-07-04 15:33:09 +02:00
parent dee1477472
commit 5551c7d7c2
6 changed files with 35 additions and 43 deletions

View file

@ -12,9 +12,11 @@
<Package name="ch.ethz.seb.sebserver.webservice.datalayer.batis.model"/> <Package name="ch.ethz.seb.sebserver.webservice.datalayer.batis.model"/>
</Match> </Match>
<Match> <Match>
<Class name="ch.ethz.seb.sebserver.gui.widget.MultiSelectionCombo" /> <Package name="ch.ethz.seb.sebserver.gui.widget" />
<Class name="ch.ethz.seb.sebserver.gui.widget.GridTable" />
<Bug pattern="SE_BAD_FIELD" /> <Bug pattern="SE_BAD_FIELD" />
</Match> </Match>
</FindBugsFilter> </FindBugsFilter>

View file

@ -47,14 +47,21 @@ public interface ExamSessionService {
void streamDefaultExamConfig(String connectionToken, OutputStream out); void streamDefaultExamConfig(String connectionToken, OutputStream out);
/** Get current ClientConnectionData for a specified active SEB client connection. /** Get current ClientConnectionData for a specified active SEB client connection.
* *
* active SEB client connections are connections that were initialized by a SEB client
* on the particular server instance.
*
* @param connectionToken the connection token of the active SEB client connection * @param connectionToken the connection token of the active SEB client connection
* @return */ * @return */
Result<ClientConnectionData> getConnectionData(String connectionToken); Result<ClientConnectionData> getConnectionData(String connectionToken);
/** Get the collection of ClientConnectionData of all active SEB client connections /** Get the collection of ClientConnectionData of all active SEB client connections
* of a running exam. * of a running exam.
* *
* active SEB client connections are connections that were initialized by a SEB client
* on the particular server instance. This may not be the all connections of an exam but
* a subset of them.
*
* @param examId The exam identifier * @param examId The exam identifier
* @return collection of ClientConnectionData of all active SEB client connections * @return collection of ClientConnectionData of all active SEB client connections
* of a running exam */ * of a running exam */

View file

@ -9,7 +9,6 @@
package ch.ethz.seb.sebserver.webservice.servicelayer.session; package ch.ethz.seb.sebserver.webservice.servicelayer.session;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
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;
import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Result;
@ -100,12 +99,6 @@ public interface SebClientConnectionService {
Long institutionId, Long institutionId,
String clientAddress); String clientAddress);
/** Get ClientConnectionData for an active connection (connection on running exam)
*
* @param connectionToken The connection token of the connection to get the ClientConnectionData from
* @return ClientConnectionData for an active connection (connection on running exam) */
Result<ClientConnectionData> getActiveConnectionData(String connectionToken);
/** Notify a ping for a certain client connection. /** Notify a ping for a certain client connection.
* *
* @param connectionToken the connection token * @param connectionToken the connection token

View file

@ -17,6 +17,8 @@ import java.util.stream.Collectors;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -40,15 +42,18 @@ public class ExamSessionServiceImpl implements ExamSessionService {
private final ClientConnectionDAO clientConnectionDAO; private final ClientConnectionDAO clientConnectionDAO;
private final ExamSessionCacheService examSessionCacheService; private final ExamSessionCacheService examSessionCacheService;
private final ExamDAO examDAO; private final ExamDAO examDAO;
private final CacheManager cacheManager;
protected ExamSessionServiceImpl( protected ExamSessionServiceImpl(
final ExamSessionCacheService examSessionCacheService, final ExamSessionCacheService examSessionCacheService,
final ExamDAO examDAO, final ExamDAO examDAO,
final ClientConnectionDAO clientConnectionDAO) { final ClientConnectionDAO clientConnectionDAO,
final CacheManager cacheManager) {
this.examSessionCacheService = examSessionCacheService; this.examSessionCacheService = examSessionCacheService;
this.examDAO = examDAO; this.examDAO = examDAO;
this.clientConnectionDAO = clientConnectionDAO; this.clientConnectionDAO = clientConnectionDAO;
this.cacheManager = cacheManager;
} }
@Override @Override
@ -147,25 +152,24 @@ public class ExamSessionServiceImpl implements ExamSessionService {
@Override @Override
public Result<ClientConnectionData> getConnectionData(final String connectionToken) { public Result<ClientConnectionData> getConnectionData(final String connectionToken) {
final ClientConnectionDataInternal activeClientConnection = this.examSessionCacheService return Result.tryCatch(() -> {
.getActiveClientConnection(connectionToken); final Cache cache = this.cacheManager.getCache(ExamSessionCacheService.CACHE_NAME_ACTIVE_CLIENT_CONNECTION);
return cache.get(connectionToken, ClientConnectionData.class);
if (activeClientConnection == null) { });
log.error("No active ClientConnection found for token: {}", connectionToken);
return Result.ofError(new IllegalArgumentException("No active ClientConnection found for token"));
} else {
return Result.of(activeClientConnection);
}
} }
@Override @Override
public Result<Collection<ClientConnectionData>> getConnectionData(final Long examId) { public Result<Collection<ClientConnectionData>> getConnectionData(final Long examId) {
return this.clientConnectionDAO return Result.tryCatch(() -> {
.getConnectionTokens(examId) final Cache cache = this.cacheManager.getCache(ExamSessionCacheService.CACHE_NAME_ACTIVE_CLIENT_CONNECTION);
.map(all -> all return this.clientConnectionDAO
.stream() .getConnectionTokens(examId)
.map(this.examSessionCacheService::getActiveClientConnection) .getOrThrow()
.collect(Collectors.toList())); .stream()
.map(token -> cache.get(token, ClientConnectionData.class))
.filter(data -> data != null)
.collect(Collectors.toList());
});
} }
private void flushCache(final Exam exam) { private void flushCache(final Exam exam) {

View file

@ -20,7 +20,6 @@ import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType; import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; 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.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;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Result;
@ -339,19 +338,6 @@ public class SebClientConnectionServiceImpl implements SebClientConnectionServic
}); });
} }
@Override
public Result<ClientConnectionData> getActiveConnectionData(final String connectionToken) {
final ClientConnectionDataInternal activeClientConnection = this.examSessionCacheService
.getActiveClientConnection(connectionToken);
if (activeClientConnection == null) {
return Result
.ofError(new IllegalArgumentException("No active client connection found for connectionToken"));
} else {
return Result.of(activeClientConnection);
}
}
@Override @Override
public void notifyPing( public void notifyPing(
final String connectionToken, final String connectionToken,

View file

@ -259,8 +259,8 @@ public class ExamAPI_V1_Controller {
handshakeUpdate(connectionToken, Long.valueOf(examId), null, principal, request); handshakeUpdate(connectionToken, Long.valueOf(examId), null, principal, request);
} }
final ClientConnectionData connection = this.sebClientConnectionService final ClientConnectionData connection = this.examSessionService
.getActiveConnectionData(connectionToken) .getConnectionData(connectionToken)
.getOrThrow(); .getOrThrow();
// exam integrity check // exam integrity check