SEBSERV-255 added automated deletion of client notification on exam

deletion
This commit is contained in:
anhefti 2022-01-05 09:00:31 +01:00
parent dfdd16a728
commit 30b0c93186
5 changed files with 74 additions and 1 deletions

View file

@ -16,6 +16,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.Domain;
import ch.ethz.seb.sebserver.gbl.util.Pair;
@ -95,6 +96,11 @@ public class ClientNotification extends ClientEvent {
return this.notificationType;
}
@Override
public EntityType entityType() {
return EntityType.CLIENT_NOTIFICATION;
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();

View file

@ -13,6 +13,7 @@ import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
import ch.ethz.seb.sebserver.gbl.model.session.ClientNotification;
import ch.ethz.seb.sebserver.gbl.model.session.ExtendedClientEvent;
@ -67,4 +68,12 @@ public interface ClientEventDAO extends EntityDAO<ClientEvent, ClientEvent> {
* @return Result refer to the confirmed notification or to en error when happened */
Result<ClientNotification> confirmPendingNotification(Long notificationId);
/** Used to get all client notification identifiers/PKs that are mapped to a specified exam.
*
* @param examId The identifier/PK of the exam
* @return Result refer to a set of client notification identifiers or to an error when happened */
Result<Set<EntityKey>> getNotificationIdsForExam(Long examId);
Result<Collection<EntityKey>> deleteClientNotification(Set<EntityKey> keys);
}

View file

@ -204,6 +204,26 @@ public class ClientEventDAOImpl implements ClientEventDAO {
.flatMap(ClientEventDAOImpl::toDomainModel);
}
@Override
@Transactional(readOnly = true)
public Result<Set<EntityKey>> getNotificationIdsForExam(final Long examId) {
return Result.tryCatch(() -> this.clientNotificationRecordMapper
.selectByExample()
.leftJoin(ClientConnectionRecordDynamicSqlSupport.clientConnectionRecord)
.on(
ClientConnectionRecordDynamicSqlSupport.id,
equalTo(ClientNotificationRecordDynamicSqlSupport.clientConnectionId))
.where(
ClientConnectionRecordDynamicSqlSupport.examId,
isEqualToWhenPresent(examId))
.build()
.execute()
.stream()
.map(ClientNotificationRecord::getClientConnectionId)
.map(id -> new EntityKey(id, EntityType.CLIENT_NOTIFICATION))
.collect(Collectors.toSet()));
}
@Override
@Transactional(readOnly = true)
public Result<ClientNotification> getPendingNotificationByValue(
@ -377,6 +397,30 @@ public class ClientEventDAOImpl implements ClientEventDAO {
});
}
@Override
@Transactional
public Result<Collection<EntityKey>> deleteClientNotification(final Set<EntityKey> keys) {
return Result.tryCatch(() -> {
final List<Long> pks = keys
.stream()
.map(EntityKey::getModelId)
.map(Long::parseLong)
.collect(Collectors.toList());
this.clientNotificationRecordMapper
.deleteByExample()
.where(ClientNotificationRecordDynamicSqlSupport.id, isIn(pks))
.build()
.execute();
return pks
.stream()
.map(pk -> new EntityKey(String.valueOf(pk), EntityType.CLIENT_NOTIFICATION))
.collect(Collectors.toList());
});
}
private Result<ClientEventRecord> recordById(final Long id) {
return Result.tryCatch(() -> {

View file

@ -451,7 +451,7 @@ public class ExamDAOImpl implements ExamDAO {
final List<Long> ids = extractListOfPKs(all);
// notify exam deletition listener about following deletion, to cleanup stuff before deletion
// notify exam deletion listener about following deletion, to cleanup stuff before deletion
this.applicationEventPublisher.publishEvent(new ExamDeletionEvent(ids));
this.examRecordMapper.deleteByExample()

View file

@ -18,6 +18,7 @@ import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.Constants;
@ -32,6 +33,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
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.impl.ExamDeletionEvent;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientInstructionService;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.SEBClientNotificationService;
@ -122,6 +124,18 @@ public class SEBClientNotificationServiceImpl implements SEBClientNotificationSe
.onError(error -> log.error("Failed to store new client notification: {}", notification, error));
}
@EventListener(ExamDeletionEvent.class)
public void notifyExamDeletionEvent(final ExamDeletionEvent event) {
// delete all notifications for given exams
event.ids.forEach(id -> this.clientEventDAO.getNotificationIdsForExam(id)
.flatMap(this.clientEventDAO::deleteClientNotification)
.map(deleted -> {
log.debug("Deleted client notifications during exam deletion: {}", deleted);
return deleted;
})
.onError(error -> log.error("Failed to delete client notifications for exam: {}", id, error)));
}
private ClientNotification notifyNewNotifiaction(final ClientNotification notification) {
if (notification.eventType == EventType.NOTIFICATION) {
this.pendingNotifications.add(notification.id);