From a8cd65037543f42193bb5b17b13e92f6ca11ab66 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 14 Mar 2018 15:17:08 +0100 Subject: [PATCH] DDI improvements and Maintenance Window states in UI (#658) * Add DDI status and tests. Signed-off-by: kaizimmerm * Add new downloaded status to UI. Signed-off-by: kaizimmerm * Reduce message noise. Signed-off-by: kaizimmerm * Fix sonar issue. Signed-off-by: kaizimmerm --- .../hawkbit/ddi/json/model/DdiStatus.java | 7 +++- .../ddi/rest/resource/DdiRootController.java | 39 ++++++++++++------- .../model/TotalTargetCountStatus.java | 1 + .../jpa/ControllerManagementTest.java | 33 ++++++++++------ .../actionhistory/ActionHistoryGrid.java | 2 + .../actionhistory/ActionStatusIconMapper.java | 2 + .../RolloutGroupTargetsListGrid.java | 2 + 7 files changed, 60 insertions(+), 26 deletions(-) diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiStatus.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiStatus.java index 6af4a7cf2..3df40334c 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiStatus.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiStatus.java @@ -106,7 +106,12 @@ public class DdiStatus { /** * The action has been downloaded by the target. */ - DOWNLOADED("downloaded"); + DOWNLOADED("downloaded"), + + /** + * Target starts to download. + */ + DOWNLOAD("download"); private String name; diff --git a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java index fb3ad1a83..88eed4c95 100644 --- a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java +++ b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java @@ -67,6 +67,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.server.ServletServerHttpRequest; +import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -363,49 +364,61 @@ public class DdiRootController implements DdiRootControllerRestApi { final Long actionid) { final List messages = new ArrayList<>(); + + if (!CollectionUtils.isEmpty(feedback.getStatus().getDetails())) { + messages.addAll(feedback.getStatus().getDetails()); + } + Status status; switch (feedback.getStatus().getExecution()) { case CANCELED: LOG.debug("Controller confirmed cancel (actionid: {}, controllerId: {}) as we got {} report.", actionid, controllerId, feedback.getStatus().getExecution()); status = Status.CANCELED; - messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target confirmed cancelation."); + addMessageIfEmpty("Target confirmed cancelation.", messages); break; case REJECTED: LOG.info("Controller reported internal error (actionid: {}, controllerId: {}) as we got {} report.", actionid, controllerId, feedback.getStatus().getExecution()); status = Status.WARNING; - messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target REJECTED update."); + addMessageIfEmpty("Target REJECTED update", messages); break; case CLOSED: status = handleClosedCase(feedback, controllerId, actionid, messages); break; + case DOWNLOAD: + LOG.debug("Controller confirmed status of download (actionId: {}, controllerId: {}) as we got {} report.", + actionid, controllerId, feedback.getStatus().getExecution()); + status = Status.DOWNLOAD; + addMessageIfEmpty("Target confirmed download start", messages); + break; case DOWNLOADED: LOG.debug("Controller confirmed download (actionId: {}, controllerId: {}) as we got {} report.", actionid, controllerId, feedback.getStatus().getExecution()); status = Status.DOWNLOADED; - messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target confirmed download of distribution set."); + addMessageIfEmpty("Target confirmed download finished", messages); break; default: status = handleDefaultCase(feedback, controllerId, actionid, messages); break; } - if (feedback.getStatus().getDetails() != null) { - messages.addAll(feedback.getStatus().getDetails()); - } - return entityFactory.actionStatus().create(actionid).status(status).messages(messages); } + private static void addMessageIfEmpty(final String text, final List messages) { + if (messages != null && messages.isEmpty()) { + messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + text + "."); + } + } + private Status handleDefaultCase(final DdiActionFeedback feedback, final String controllerId, final Long actionid, final List messages) { Status status; LOG.debug("Controller reported intermediate status (actionid: {}, controllerId: {}) as we got {} report.", actionid, controllerId, feedback.getStatus().getExecution()); status = Status.RUNNING; - messages.add( - RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target reported " + feedback.getStatus().getExecution()); + addMessageIfEmpty("Target reported " + feedback.getStatus().getExecution(), messages); return status; } @@ -416,10 +429,10 @@ public class DdiRootController implements DdiRootControllerRestApi { controllerId, feedback.getStatus().getExecution()); if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) { status = Status.ERROR; - messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target reported CLOSED with ERROR!"); + addMessageIfEmpty("Target reported CLOSED with ERROR!", messages); } else { status = Status.FINISHED; - messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target reported CLOSED with OK!"); + addMessageIfEmpty("Target reported CLOSED with OK!", messages); } return status; } @@ -525,10 +538,10 @@ public class DdiRootController implements DdiRootControllerRestApi { Status status; if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) { status = Status.ERROR; - messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target was not able to complete cancelation."); + addMessageIfEmpty("Target was not able to complete cancelation", messages); } else { status = Status.CANCELED; - messages.add(RepositoryConstants.SERVER_MESSAGE_PREFIX + "Cancelation confirmed."); + addMessageIfEmpty("Cancelation confirmed", messages); } return status; } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TotalTargetCountStatus.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TotalTargetCountStatus.java index 335bb8024..eed7d7bb2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TotalTargetCountStatus.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TotalTargetCountStatus.java @@ -152,6 +152,7 @@ public class TotalTargetCountStatus { case RUNNING: case WARNING: case DOWNLOAD: + case DOWNLOADED: case CANCELING: final Long runningItemsCount = statusTotalCountMap.get(Status.RUNNING) + item.getCount(); statusTotalCountMap.put(Status.RUNNING, runningItemsCount); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java index fc3322996..df7a72808 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java @@ -143,8 +143,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC, Action.Status.FINISHED, Action.Status.FINISHED, false); - assertThat(actionStatusRepository.count()).isEqualTo(6); - assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(6); + assertThat(actionStatusRepository.count()).isEqualTo(7); + assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(7); } @Test @@ -170,8 +170,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { .messages(Arrays.asList("this is valid.", INVALID_TEXT_HTML)))) .as("set invalid description text should not be created"); - assertThat(actionStatusRepository.count()).isEqualTo(5); - assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(5); + assertThat(actionStatusRepository.count()).isEqualTo(6); + assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(6); } @Test @@ -246,8 +246,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC, Action.Status.CANCELED, Action.Status.FINISHED, false); - assertThat(actionStatusRepository.count()).isEqualTo(7); - assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(7); + assertThat(actionStatusRepository.count()).isEqualTo(8); + assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(8); } @Test @@ -273,8 +273,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.IN_SYNC, Action.Status.CANCELED, Action.Status.CANCELED, false); - assertThat(actionStatusRepository.count()).isEqualTo(7); - assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(7); + assertThat(actionStatusRepository.count()).isEqualTo(8); + assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(8); } @Test @@ -301,8 +301,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING, Action.Status.RUNNING, Action.Status.CANCEL_REJECTED, true); - assertThat(actionStatusRepository.count()).isEqualTo(7); - assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(7); + assertThat(actionStatusRepository.count()).isEqualTo(8); + assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(8); } @Test @@ -329,8 +329,8 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING, Action.Status.RUNNING, Action.Status.ERROR, true); - assertThat(actionStatusRepository.count()).isEqualTo(7); - assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(7); + assertThat(actionStatusRepository.count()).isEqualTo(8); + assertThat(controllerManagement.findActionStatusByAction(PAGE, actionId).getNumberOfElements()).isEqualTo(8); } @Step @@ -357,6 +357,11 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING, Action.Status.CANCELING, Action.Status.DOWNLOAD, true); + controllerManagement + .addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.DOWNLOADED)); + assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING, + Action.Status.CANCELING, Action.Status.DOWNLOADED, true); + controllerManagement .addCancelActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.RETRIEVED)); assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING, @@ -379,6 +384,10 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { .addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.DOWNLOAD)); assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING, Action.Status.RUNNING, Action.Status.DOWNLOAD, true); + controllerManagement + .addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.DOWNLOADED)); + assertActionStatus(actionId, TestdataFactory.DEFAULT_CONTROLLER_ID, TargetUpdateStatus.PENDING, + Action.Status.RUNNING, Action.Status.DOWNLOADED, true); controllerManagement .addUpdateActionStatus(entityFactory.actionStatus().create(actionId).status(Action.Status.RETRIEVED)); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java index 9300e9f51..3addfaa4c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryGrid.java @@ -724,6 +724,8 @@ public class ActionHistoryGrid extends AbstractGrid { i18n.getMessage("label.cancelled"), statusLabelId)); stateMap.put(Action.Status.RETRIEVED, new StatusFontIcon(FontAwesome.CIRCLE_O, STATUS_ICON_PENDING, i18n.getMessage("label.retrieved"), statusLabelId)); + stateMap.put(Action.Status.DOWNLOADED, new StatusFontIcon(FontAwesome.CLOUD_DOWNLOAD, STATUS_ICON_GREEN, + i18n.getMessage("label.downloaded"), statusLabelId)); stateMap.put(Action.Status.DOWNLOAD, new StatusFontIcon(FontAwesome.CLOUD_DOWNLOAD, STATUS_ICON_PENDING, i18n.getMessage("label.download"), statusLabelId)); stateMap.put(Action.Status.SCHEDULED, new StatusFontIcon(FontAwesome.HOURGLASS_1, STATUS_ICON_PENDING, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java index 026cffd95..3a6fcfb63 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionStatusIconMapper.java @@ -46,6 +46,8 @@ public final class ActionStatusIconMapper { SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.CIRCLE_O)); MAPPINGS.put(Action.Status.DOWNLOAD, new ActionStatusIconMapper("label.download", SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.CLOUD_DOWNLOAD)); + MAPPINGS.put(Action.Status.DOWNLOADED, new ActionStatusIconMapper("label.downloaded", + SPUIStyleDefinitions.STATUS_ICON_GREEN, FontAwesome.CLOUD_DOWNLOAD)); MAPPINGS.put(Action.Status.SCHEDULED, new ActionStatusIconMapper("label.scheduled", SPUIStyleDefinitions.STATUS_ICON_PENDING, FontAwesome.HOURGLASS_1)); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListGrid.java index f39756f5c..64d807f8d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsListGrid.java @@ -60,6 +60,8 @@ public class RolloutGroupTargetsListGrid extends AbstractGrid