Skip to content

Commit

Permalink
SEBSERV-440 implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
anhefti committed Nov 27, 2023
1 parent 0d5d7b3 commit 50456b8
Show file tree
Hide file tree
Showing 23 changed files with 745 additions and 462 deletions.
5 changes: 4 additions & 1 deletion src/main/java/ch/ethz/seb/sebserver/gbl/api/APIMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ public enum ErrorMessage {
EXAM_IMPORT_ERROR_AUTO_CONFIG("1610", HttpStatus.PARTIAL_CONTENT,
"Failed to automatically create and link exam configuration from the exam template to the exam"),
EXAM_IMPORT_ERROR_AUTO_CONFIG_LINKING("1611", HttpStatus.PARTIAL_CONTENT,
"Failed to automatically link auto-generated exam configuration to the exam");
"Failed to automatically link auto-generated exam configuration to the exam"),

CLIENT_CONNECTION_INTEGRITY_VIOLATION("1700", HttpStatus.NOT_ACCEPTABLE,
"SEB client connection is not in valid state to apply requested operation");

public final String messageCode;
public final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ public String toString() {
builder.append(this.clientAddress);
builder.append(", remoteProctoringRoomId=");
builder.append(this.remoteProctoringRoomId);
builder.append(", virtualClientId=");
builder.append(", sebClientUserId=");
builder.append(this.sebClientUserId);
builder.append(", creationTime=");
builder.append(this.creationTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ public Result<ClientConnection> createNew(final ClientConnection data) {
data.examId,
ConnectionStatus.CONNECTION_REQUESTED.name(),
data.connectionToken,
null,
data.userSessionId,
data.clientAddress,
data.sebClientUserId,
BooleanUtils.toInteger(data.vdi, 1, 0, 0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

package ch.ethz.seb.sebserver.webservice.servicelayer.session;

import javax.servlet.http.HttpServletResponse;
import java.security.Principal;
import java.util.Collection;

Expand Down Expand Up @@ -158,4 +159,18 @@ Result<ClientConnection> closeConnection(
* happened */
Result<Collection<EntityKey>> disableConnections(final String[] connectionTokens, final Long institutionId);

/** Streams the requested exam configuration to given HttpServletResponse output stream
*
* @param institutionId the institution identifier
* @param examId the exam identifier
* @param connectionToken the connection identifier token
* @param ipAddress the IP Address of the SEB client request
* @param response HttpServletResponse instance to stream the exam configuration to */
void streamExamConfig(
Long institutionId,
Long examId,
String connectionToken,
String ipAddress,
HttpServletResponse response);

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;

/** Service for SEB instruction handling.
*
* <p>
* SEB instructions are sent as response of a SEB Ping on a active SEB Connection
* If there is an instruction in the queue for a specified SEB Client. */
public interface SEBClientInstructionService {

static final Logger log = LoggerFactory.getLogger(SEBClientInstructionService.class);
Logger log = LoggerFactory.getLogger(SEBClientInstructionService.class);

/** Get the underling WebserviceInfo
*
Expand All @@ -46,10 +46,10 @@ public interface SEBClientInstructionService {
void init();

/** Used to register a SEB client instruction for one or more active client connections
* within an other background thread. This is none-blocking.
* within another background thread. This is none-blocking.
*
* @param clientInstruction the ClientInstruction instance to register
* @return A Result refer to a void marker or to an error if happened */
**/
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
default void registerInstructionAsync(final ClientInstruction clientInstruction) {
registerInstruction(clientInstruction, false)
Expand All @@ -69,7 +69,7 @@ default Result<Void> registerInstruction(final ClientInstruction clientInstructi
/** Used to register a SEB client instruction for one or more active client connections
*
* @param clientInstruction the ClientInstruction instance to register
* @param needsConfirm indicates whether the SEB instruction needs a confirmation or not
* @param needsConfirmation indicates whether the SEB instruction needs a confirmation or not
* @return A Result refer to a void marker or to an error if happened */
default Result<Void> registerInstruction(
final ClientInstruction clientInstruction,
Expand All @@ -91,13 +91,15 @@ default Result<Void> registerInstruction(
* @param type The InstructionType
* @param attributes The instruction's attributes
* @param connectionToken a connectionToken to register the instruction for.
* @param checkActive indicates if the involved client connection shall be checked for active status or not
* @param needsConfirm indicates whether the SEB instruction needs a confirmation or not
* @return A Result refer to a void marker or to an error if happened */
Result<Void> registerInstruction(
final Long examId,
InstructionType type,
Map<String, String> attributes,
String connectionToken,
boolean checkActive,
boolean needsConfirm);

/** Used to register a SEB client instruction for one or more active client connections
Expand All @@ -117,9 +119,9 @@ Result<Void> registerInstruction(

/** Get a SEB instruction for the specified SEB Client connection or null of there
* is currently no SEB instruction in the queue.
*
* <p>
* NOTE: If this call returns a SEB instruction instance, this instance is considered
* as processed for the specified SEB Client afterwards and will be removed from the queue
* as processed for the specified SEB Client afterward and will be removed from the queue
*
* @param connectionToken the SEB Client connection token
* @return SEB instruction to sent to the SEB Client or null */
Expand All @@ -131,7 +133,7 @@ Result<Void> registerInstruction(
* @param instructionConfirm the instruction confirm identifier */
void confirmInstructionDone(String connectionToken, String instructionConfirm);

/** Used to cleanup out-dated instructions on the persistent storage */
/** Used to clean up out-dated instructions on the persistent storage */
void cleanupInstructions();

}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ default void processSessionUpdateTask() {
/** Used to update the app signature key grants of all active SEB connections that miss a grant */
void updateASKGrants();

/** Used to cleanup old instructions from the persistent storage */
/** Used to clean up old instructions from the persistent storage */
void cleanupInstructions();

/** Notify a ping for a certain client connection.
Expand All @@ -66,7 +66,7 @@ default void processSessionUpdateTask() {
* @param instructionConfirm the instruction confirm identifier */
void confirmInstructionDone(String connectionToken, String instructionConfirm);

/** Use this to get the get the specific indicator values for a given client connection.
/** Use this to get the specific indicator values for a given client connection.
*
* @param clientConnection The client connection values
* @return Result refer to ClientConnectionData instance containing the given clientConnection plus the indicator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,27 +227,30 @@ public synchronized Result<Exam> getRunningExam(final Long examId) {
updateExamCache(examId);
}

final Exam exam = this.examSessionCacheService.getRunningExam(examId);
return Result.tryCatch(() -> {

if (this.examSessionCacheService.isRunning(exam)) {
if (log.isTraceEnabled()) {
log.trace("Exam {} is running and cached", examId);
}
final Exam exam = this.examSessionCacheService.getRunningExam(examId);

return Result.of(exam);
} else {
if (exam != null) {
log.info("Exam {} is not running anymore. Flush caches", exam);
flushCache(exam);
}
if (this.examSessionCacheService.isRunning(exam)) {
if (log.isTraceEnabled()) {
log.trace("Exam {} is running and cached", examId);
}

if (log.isDebugEnabled()) {
log.info("Exam {} is not currently running", examId);
}
return exam;
} else {
if (exam != null) {
log.info("Exam {} is not running anymore. Flush caches", exam);
flushCache(exam);
}

return Result.ofError(new NoSuchElementException(
"No currently running exam found for id: " + examId));
}
if (log.isDebugEnabled()) {
log.info("Exam {} is not currently running", examId);
}

throw new NoSuchElementException(
"No currently running exam found for id: " + examId);
}
});
}

@Override
Expand Down
Loading

0 comments on commit 50456b8

Please sign in to comment.