From 70358d0128f2a19778b4905279bc4614a6bab974 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 22 Sep 2021 16:55:28 +0200 Subject: [PATCH] fixed session id, exam delete, ane better logs --- .../gui/content/ExamDeletePopup.java | 25 ++++++++++++++++++- .../session/ClientConnectionTable.java | 9 +++++-- .../impl/BulkActionServiceImpl.java | 4 +-- .../impl/SEBClientConnectionServiceImpl.java | 15 +++++++---- .../weblayer/api/EntityController.java | 7 ++++++ .../api/ExamAdministrationController.java | 5 ++++ src/main/resources/messages.properties | 1 + 7 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamDeletePopup.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamDeletePopup.java index a8b37306..f3811264 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamDeletePopup.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamDeletePopup.java @@ -26,16 +26,20 @@ import org.springframework.stereotype.Component; import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType; +import ch.ethz.seb.sebserver.gbl.api.APIMessage; +import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage; import ch.ethz.seb.sebserver.gbl.model.EntityDependency; import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport; import ch.ethz.seb.sebserver.gbl.model.exam.Exam; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; +import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition; import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.page.PageContext; +import ch.ethz.seb.sebserver.gui.service.page.PageMessageException; import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.event.ActionEvent; import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputWizard; @@ -43,6 +47,7 @@ import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputWizard.WizardAction import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputWizard.WizardPage; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCallError; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteExam; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamDependencies; @@ -76,6 +81,8 @@ public class ExamDeletePopup { private final static LocTextKey DELETE_CONFIRM_TITLE = new LocTextKey("sebserver.exam.delete.confirm.title"); + private final static LocTextKey DELETE_ERROR_CONSISTENCY = + new LocTextKey("sebserver.exam.action.delete.consistency.error"); private final PageService pageService; @@ -126,7 +133,23 @@ public class ExamDeletePopup { .withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId) .withQueryParam(API.PARAM_BULK_ACTION_TYPE, BulkActionType.HARD_DELETE.name()); - final EntityProcessingReport report = restCallBuilder.call().getOrThrow(); + final Result deleteCall = restCallBuilder.call(); + if (deleteCall.hasError()) { + final Exception error = deleteCall.getError(); + if (error instanceof RestCallError) { + final APIMessage message = ((RestCallError) error) + .getAPIMessages() + .stream() + .findFirst() + .orElse(null); + if (message != null && ErrorMessage.INTEGRITY_VALIDATION.isOf(message)) { + pageContext.publishPageMessage(new PageMessageException(DELETE_ERROR_CONSISTENCY)); + return false; + } + } + } + + final EntityProcessingReport report = deleteCall.getOrThrow(); final PageAction action = this.pageService.pageActionBuilder(pageContext) .newAction(ActionDefinition.EXAM_VIEW_LIST) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java index 2e61b70a..7a8053d0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/ClientConnectionTable.java @@ -293,8 +293,13 @@ public final class ClientConnectionTable { final Set result = new HashSet<>(); for (int i = 0; i < selectionIndices.length; i++) { final UpdatableTableItem updatableTableItem = - new ArrayList<>(this.tableMapping.values()).get(selectionIndices[0]); - result.add(new EntityKey(updatableTableItem.connectionId, EntityType.CLIENT_CONNECTION)); + new ArrayList<>(this.tableMapping.values()) + .stream() + .findFirst() + .orElse(null); + if (updatableTableItem != null) { + result.add(new EntityKey(updatableTableItem.connectionId, EntityType.CLIENT_CONNECTION)); + } } return result; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java index c6fb3825..42e0ba88 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/impl/BulkActionServiceImpl.java @@ -165,8 +165,8 @@ public class BulkActionServiceImpl implements BulkActionService { final Exception error = bulkActionSingleResult.getError(); log.error( - "Unexpected error on bulk action processing. This error is reported to the caller: {}", - error.getMessage()); + "Unexpected error on bulk action processing. This error is reported to the caller: ", + error); if (error instanceof BulkActionEntityException) { return new ErrorEntry( diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java index d498b69d..8050e036 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientConnectionServiceImpl.java @@ -675,11 +675,16 @@ public class SEBClientConnectionServiceImpl implements SEBClientConnectionServic if (StringUtils.isNoneBlank(userSessionId)) { if (StringUtils.isNoneBlank(clientConnection.userSessionId)) { - log.error( - "ClientConnection integrity violation: clientConnection has already a userSessionId: {} : {}", - userSessionId, clientConnection); - throw new IllegalArgumentException( - "ClientConnection integrity violation: clientConnection has already a userSessionId"); + if (clientConnection.userSessionId.contains(userSessionId)) { + if (log.isDebugEnabled()) { + log.debug("SEB sent LMS userSessionId but clientConnection has already a userSessionId"); + } + } else { + log.warn( + "Possible client integrity violation: clientConnection has already a userSessionId: {} : {}", + userSessionId, clientConnection.userSessionId); + } + return clientConnection; } // try to get user account display name diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java index 6dfaa421..39a8e0d6 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java @@ -372,6 +372,13 @@ public abstract class EntityController { final EntityType entityType = this.entityDAO.entityType(); final Collection sources = ids.stream() + .map(id -> { + return this.entityDAO.byModelId(id) + .flatMap(exam -> this.validForDelete(exam)) + .getOr(null); + }) + .filter(Objects::nonNull) + .map(exam -> exam.getModelId()) .map(id -> new EntityKey(id, entityType)) .collect(Collectors.toList()); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java index 8324b03e..30946768 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java @@ -495,6 +495,11 @@ public class ExamAdministrationController extends EntityController { } } + @Override + protected Result validForDelete(final Exam entity) { + return checkNoActiveSEBClientConnections(entity); + } + private Exam checkExamSupporterRole(final Exam exam) { final Set examSupporter = this.userDAO.all( this.authorization.getUserService().getCurrentUser().getUserInfo().institutionId, diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 88910fca..051d5ed0 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -451,6 +451,7 @@ sebserver.exam.action.save=Save Exam sebserver.exam.action.activate=Activate Exam sebserver.exam.action.deactivate=Deactivate Exam sebserver.exam.action.delete=Delete Exam +sebserver.exam.action.delete.consistency.error=Deletion Failed.
Please make sure there are no active SEB clients connected to the exam before deletion. sebserver.exam.action.sebrestriction.enable=Apply SEB Lock sebserver.exam.action.sebrestriction.disable=Release SEB Lock sebserver.exam.action.sebrestriction.details=SEB Restriction Details