Integrated Maintenance Window fields in Management API and UI (#677)
* Added Maintenance Window properties to API and UI * extended Management API with Maintenance Window schedule, duration, timezone and nextAt properties * extended integration tests for the above properties * extended Management UI with Maintenance Window column in Action History grid, added tooltip for next execution * general refactoring Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * fixed Sonar issues Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * changed the documentation help link for maintenance window Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * added licence header, first refactoring after partial PR review Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * changes related to PR review findings Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com> * last PR review findings Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>
This commit is contained in:
committed by
Dominic Schabel
parent
1deb47a4db
commit
b5114081be
@@ -8,12 +8,16 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.ui.common.grid;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.ui.SpPermissionChecker;
|
||||
import org.eclipse.hawkbit.ui.components.RefreshableContainer;
|
||||
import org.eclipse.hawkbit.ui.management.actionhistory.ProxyAction;
|
||||
import org.eclipse.hawkbit.ui.management.actionhistory.ProxyActionStatus;
|
||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||
@@ -284,8 +288,8 @@ public abstract class AbstractGrid<T extends Indexed> extends Grid implements Re
|
||||
|
||||
/**
|
||||
* Template method invoked by {@link this#addNewContainerDS()} for adding
|
||||
* properties to the container (usually by invoing
|
||||
* {@link Container#addContainerProperty(Object, Class, Object))})
|
||||
* properties to the container (usually by invoking { @link
|
||||
* Container#addContainerProperty(Object, Class, Object))})
|
||||
*/
|
||||
protected abstract void addContainerProperties();
|
||||
|
||||
@@ -581,7 +585,7 @@ public abstract class AbstractGrid<T extends Indexed> extends Grid implements Re
|
||||
* CellStyleGenerator that concerns about alignment in the grid cells.
|
||||
*/
|
||||
protected static class AlignCellStyleGenerator implements CellStyleGenerator {
|
||||
private static final long serialVersionUID = 5573570647129792429L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String[] left;
|
||||
private final String[] center;
|
||||
@@ -621,29 +625,40 @@ public abstract class AbstractGrid<T extends Indexed> extends Grid implements Re
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tooltip to the 'Date and time' column in detailed format.
|
||||
* Adds a tooltip to the 'Date and time' and 'Maintenance Window' columns in
|
||||
* detailed format.
|
||||
*/
|
||||
public static class ModifiedTimeTooltipGenerator implements CellDescriptionGenerator {
|
||||
private static final long serialVersionUID = -6617911967167729195L;
|
||||
protected static class TooltipGenerator implements CellDescriptionGenerator {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final String datePropertyId;
|
||||
private final VaadinMessageSource i18n;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param datePropertyId
|
||||
*/
|
||||
public ModifiedTimeTooltipGenerator(final String datePropertyId) {
|
||||
this.datePropertyId = datePropertyId;
|
||||
public TooltipGenerator(final VaadinMessageSource i18n) {
|
||||
this.i18n = i18n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(final CellReference cell) {
|
||||
if (!datePropertyId.equals(cell.getPropertyId())) {
|
||||
final String propertyId = (String) cell.getPropertyId();
|
||||
switch (propertyId) {
|
||||
case ProxyAction.PXY_ACTION_LAST_MODIFIED_AT:
|
||||
case ProxyActionStatus.PXY_AS_CREATED_AT:
|
||||
final Long timestamp = (Long) cell.getItem().getItemProperty(propertyId).getValue();
|
||||
return SPDateTimeUtil.getFormattedDate(timestamp);
|
||||
|
||||
case ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW:
|
||||
final Action action = (Action) cell.getItem().getItemProperty(ProxyAction.PXY_ACTION).getValue();
|
||||
return action.getMaintenanceWindowStartTime().map(this::getFormattedNextMaintenanceWindow).orElse(null);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
final Long timestamp = (Long) cell.getItem().getItemProperty(datePropertyId).getValue();
|
||||
return SPDateTimeUtil.getFormattedDate(timestamp);
|
||||
}
|
||||
|
||||
private String getFormattedNextMaintenanceWindow(final ZonedDateTime nextAt) {
|
||||
final long nextAtMilli = nextAt.toInstant().toEpochMilli();
|
||||
return i18n.getMessage("tooltip.next.maintenancewindow",
|
||||
SPDateTimeUtil.getFormattedDate(nextAtMilli, SPUIDefinitions.LAST_QUERY_DATE_FORMAT_SHORT));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,12 +115,19 @@ public class ActionBeanQuery extends AbstractBeanQuery<ProxyAction> {
|
||||
proxyAction.setLastModifiedAt(action.getLastModifiedAt());
|
||||
proxyAction.setRolloutName(action.getRollout() != null ? action.getRollout().getName() : "");
|
||||
proxyAction.setStatus(action.getStatus());
|
||||
proxyAction.setMaintenanceWindow(
|
||||
action.hasMaintenanceSchedule() ? buildMaintenanceWindowDisplayText(action) : "");
|
||||
|
||||
proxyActions.add(proxyAction);
|
||||
}
|
||||
return proxyActions;
|
||||
}
|
||||
|
||||
private static String buildMaintenanceWindowDisplayText(final Action action) {
|
||||
return action.getMaintenanceWindowSchedule() + "/" + action.getMaintenanceWindowDuration() + "/"
|
||||
+ action.getMaintenanceWindowTimeZone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a virtual IsActiveDecoration for the presentation layer that is
|
||||
* calculated from {@link Action#isActive()} and
|
||||
|
||||
@@ -78,13 +78,14 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
|
||||
private static final Object[] maxColumnOrder = new Object[] { ProxyAction.PXY_ACTION_IS_ACTIVE_DECO,
|
||||
ProxyAction.PXY_ACTION_ID, ProxyAction.PXY_ACTION_DS_NAME_VERSION, ProxyAction.PXY_ACTION_LAST_MODIFIED_AT,
|
||||
ProxyAction.PXY_ACTION_STATUS, ProxyAction.PXY_ACTION_ROLLOUT_NAME, VIRT_PROP_FORCED, VIRT_PROP_TIMEFORCED,
|
||||
VIRT_PROP_ACTION_CANCEL, VIRT_PROP_ACTION_FORCE, VIRT_PROP_ACTION_FORCE_QUIT };
|
||||
ProxyAction.PXY_ACTION_STATUS, ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW,
|
||||
ProxyAction.PXY_ACTION_ROLLOUT_NAME, VIRT_PROP_FORCED, VIRT_PROP_TIMEFORCED, VIRT_PROP_ACTION_CANCEL,
|
||||
VIRT_PROP_ACTION_FORCE, VIRT_PROP_ACTION_FORCE_QUIT };
|
||||
|
||||
private static final Object[] minColumnOrder = new Object[] { ProxyAction.PXY_ACTION_IS_ACTIVE_DECO,
|
||||
ProxyAction.PXY_ACTION_DS_NAME_VERSION, ProxyAction.PXY_ACTION_LAST_MODIFIED_AT,
|
||||
ProxyAction.PXY_ACTION_STATUS, VIRT_PROP_FORCED, VIRT_PROP_TIMEFORCED, VIRT_PROP_ACTION_CANCEL,
|
||||
VIRT_PROP_ACTION_FORCE, VIRT_PROP_ACTION_FORCE_QUIT };
|
||||
ProxyAction.PXY_ACTION_STATUS, ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW, VIRT_PROP_FORCED,
|
||||
VIRT_PROP_TIMEFORCED, VIRT_PROP_ACTION_CANCEL, VIRT_PROP_ACTION_FORCE, VIRT_PROP_ACTION_FORCE_QUIT };
|
||||
|
||||
private static final String[] leftAlignedColumns = new String[] { VIRT_PROP_TIMEFORCED };
|
||||
|
||||
@@ -99,7 +100,7 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
|
||||
private Target selectedTarget;
|
||||
private final AlignCellStyleGenerator alignGenerator;
|
||||
private final ModifiedTimeTooltipGenerator modTimetooltipGenerator;
|
||||
private final TooltipGenerator tooltipGenerator;
|
||||
|
||||
private final Map<Action.Status, StatusFontIcon> states;
|
||||
private final Map<IsActiveDecoration, StatusFontIcon> activeStates;
|
||||
@@ -139,7 +140,7 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
activeStates = conf
|
||||
.createActiveStatusLabelConfig(UIComponentIdProvider.ACTION_HISTORY_TABLE_ACTIVESTATE_LABEL_ID);
|
||||
alignGenerator = new AlignCellStyleGenerator(leftAlignedColumns, centerAlignedColumns, rightAlignedColumns);
|
||||
modTimetooltipGenerator = new ModifiedTimeTooltipGenerator(ProxyAction.PXY_ACTION_LAST_MODIFIED_AT);
|
||||
tooltipGenerator = new TooltipGenerator(i18n);
|
||||
|
||||
init();
|
||||
}
|
||||
@@ -208,6 +209,7 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
|
||||
rawCont.addContainerProperty(ProxyAction.PXY_ACTION_ID, String.class, null, true, true);
|
||||
rawCont.addContainerProperty(ProxyAction.PXY_ACTION_ROLLOUT_NAME, String.class, null, true, true);
|
||||
rawCont.addContainerProperty(ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW, String.class, null, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -436,11 +438,14 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
getColumn(VIRT_PROP_ACTION_CANCEL).setHidable(false);
|
||||
getColumn(VIRT_PROP_ACTION_FORCE).setHidable(false);
|
||||
getColumn(VIRT_PROP_ACTION_FORCE_QUIT).setHidable(false);
|
||||
|
||||
getColumn(ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW).setHidden(true);
|
||||
getColumn(ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW).setHidable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CellDescriptionGenerator getDescriptionGenerator() {
|
||||
return modTimetooltipGenerator;
|
||||
return tooltipGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -451,6 +456,8 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
getColumn(ProxyAction.PXY_ACTION_DS_NAME_VERSION).setHeaderCaption(SPUIDefinitions.ACTION_HIS_TBL_DIST);
|
||||
getColumn(ProxyAction.PXY_ACTION_LAST_MODIFIED_AT).setHeaderCaption(SPUIDefinitions.ACTION_HIS_TBL_DATETIME);
|
||||
getColumn(ProxyAction.PXY_ACTION_STATUS).setHeaderCaption(SPUIDefinitions.ACTION_HIS_TBL_STATUS);
|
||||
getColumn(ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW)
|
||||
.setHeaderCaption(SPUIDefinitions.ACTION_HIS_TBL_MAINTENANCE_WINDOW);
|
||||
getColumn(VIRT_PROP_FORCED).setHeaderCaption(String.valueOf(forceClientRefreshToggle));
|
||||
forceClientRefreshToggle = !forceClientRefreshToggle;
|
||||
|
||||
@@ -463,8 +470,9 @@ public class ActionHistoryGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
protected void setColumnExpandRatio() {
|
||||
setColumnsSize(50.0, 50.0, ProxyAction.PXY_ACTION_IS_ACTIVE_DECO);
|
||||
setColumnsSize(107.0, 500.0, ProxyAction.PXY_ACTION_DS_NAME_VERSION);
|
||||
setColumnsSize(100.0, 120.0, ProxyAction.PXY_ACTION_LAST_MODIFIED_AT);
|
||||
setColumnsSize(100.0, 130.0, ProxyAction.PXY_ACTION_LAST_MODIFIED_AT);
|
||||
setColumnsSize(53.0, 55.0, ProxyAction.PXY_ACTION_STATUS);
|
||||
setColumnsSize(150.0, 200.0, ProxyAction.PXY_ACTION_MAINTENANCE_WINDOW);
|
||||
setColumnsSize(FIXED_PIX_MIN, FIXED_PIX_MIN, VIRT_PROP_FORCED, VIRT_PROP_TIMEFORCED, VIRT_PROP_ACTION_CANCEL,
|
||||
VIRT_PROP_ACTION_FORCE, VIRT_PROP_ACTION_FORCE_QUIT);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ActionStatusGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
private static final String[] centerAlignedColumns = new String[] { ProxyActionStatus.PXY_AS_STATUS };
|
||||
|
||||
private final AlignCellStyleGenerator alignGenerator;
|
||||
private final ModifiedTimeTooltipGenerator modTimetooltipGenerator;
|
||||
private final TooltipGenerator tooltipGenerator;
|
||||
|
||||
private final Map<Action.Status, StatusFontIcon> states;
|
||||
|
||||
@@ -58,7 +58,7 @@ public class ActionStatusGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
final LabelConfig conf = new ActionHistoryGrid.LabelConfig();
|
||||
states = conf.createStatusLabelConfig(i18n, UIComponentIdProvider.ACTION_STATUS_GRID_STATUS_LABEL_ID);
|
||||
alignGenerator = new AlignCellStyleGenerator(leftAlignedColumns, centerAlignedColumns, null);
|
||||
modTimetooltipGenerator = new ModifiedTimeTooltipGenerator(ProxyActionStatus.PXY_AS_CREATED_AT);
|
||||
tooltipGenerator = new TooltipGenerator(i18n);
|
||||
|
||||
init();
|
||||
}
|
||||
@@ -153,7 +153,7 @@ public class ActionStatusGrid extends AbstractGrid<LazyQueryContainer> {
|
||||
|
||||
@Override
|
||||
protected CellDescriptionGenerator getDescriptionGenerator() {
|
||||
return modTimetooltipGenerator;
|
||||
return tooltipGenerator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ public class ProxyAction implements Serializable {
|
||||
public static final String PXY_ACTION = "action";
|
||||
public static final String PXY_ACTION_LAST_MODIFIED_AT = "lastModifiedAt";
|
||||
public static final String PXY_ACTION_ROLLOUT_NAME = "rolloutName";
|
||||
public static final String PXY_ACTION_MAINTENANCE_WINDOW = "maintenanceWindow";
|
||||
|
||||
private Action.Status status;
|
||||
private boolean isActive;
|
||||
@@ -35,6 +36,15 @@ public class ProxyAction implements Serializable {
|
||||
private Action action;
|
||||
private Long lastModifiedAt;
|
||||
private String rolloutName;
|
||||
private String maintenanceWindow;
|
||||
|
||||
public String getMaintenanceWindow() {
|
||||
return maintenanceWindow;
|
||||
}
|
||||
|
||||
public void setMaintenanceWindow(final String maintenanceWindow) {
|
||||
this.maintenanceWindow = maintenanceWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id for the entry.
|
||||
@@ -51,7 +61,7 @@ public class ProxyAction implements Serializable {
|
||||
* @param id
|
||||
* of the action entry.
|
||||
*/
|
||||
public void setId(Long id) {
|
||||
public void setId(final Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@@ -70,7 +80,7 @@ public class ProxyAction implements Serializable {
|
||||
* @param status
|
||||
* literal
|
||||
*/
|
||||
public void setStatus(Action.Status status) {
|
||||
public void setStatus(final Action.Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
@@ -91,7 +101,7 @@ public class ProxyAction implements Serializable {
|
||||
* <code>true</code> if the action is active, otherwise
|
||||
* <code>false</code>
|
||||
*/
|
||||
public void setActive(boolean isActive) {
|
||||
public void setActive(final boolean isActive) {
|
||||
this.isActive = isActive;
|
||||
}
|
||||
|
||||
@@ -113,7 +123,7 @@ public class ProxyAction implements Serializable {
|
||||
* @param isActiveDecoration
|
||||
* pre-calculated literal
|
||||
*/
|
||||
public void setIsActiveDecoration(IsActiveDecoration isActiveDecoration) {
|
||||
public void setIsActiveDecoration(final IsActiveDecoration isActiveDecoration) {
|
||||
this.isActiveDecoration = isActiveDecoration;
|
||||
}
|
||||
|
||||
@@ -133,7 +143,7 @@ public class ProxyAction implements Serializable {
|
||||
* @param dsNameVersion
|
||||
* combined value
|
||||
*/
|
||||
public void setDsNameVersion(String dsNameVersion) {
|
||||
public void setDsNameVersion(final String dsNameVersion) {
|
||||
this.dsNameVersion = dsNameVersion;
|
||||
}
|
||||
|
||||
@@ -151,7 +161,7 @@ public class ProxyAction implements Serializable {
|
||||
*
|
||||
* @param action
|
||||
*/
|
||||
public void setAction(Action action) {
|
||||
public void setAction(final Action action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@@ -170,7 +180,7 @@ public class ProxyAction implements Serializable {
|
||||
* @param lastModifiedAt
|
||||
* raw long-value for lastModifiedAt-date
|
||||
*/
|
||||
public void setLastModifiedAt(Long lastModifiedAt) {
|
||||
public void setLastModifiedAt(final Long lastModifiedAt) {
|
||||
this.lastModifiedAt = lastModifiedAt;
|
||||
}
|
||||
|
||||
@@ -188,7 +198,7 @@ public class ProxyAction implements Serializable {
|
||||
*
|
||||
* @param rolloutName
|
||||
*/
|
||||
public void setRolloutName(String rolloutName) {
|
||||
public void setRolloutName(final String rolloutName) {
|
||||
this.rolloutName = rolloutName;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ public class MaintenanceWindowLayout extends VerticalLayout {
|
||||
* Text field to specify the schedule.
|
||||
*/
|
||||
private void createMaintenanceScheduleControl() {
|
||||
schedule = new TextFieldBuilder(Action.MAINTENANCE_SCHEDULE_CRON_LENGTH)
|
||||
schedule = new TextFieldBuilder(Action.MAINTENANCE_WINDOW_SCHEDULE_LENGTH)
|
||||
.id(UIComponentIdProvider.MAINTENANCE_WINDOW_SCHEDULE_ID)
|
||||
.caption(i18n.getMessage("caption.maintenancewindow.schedule")).validator(new CronValidator())
|
||||
.prompt("0 0 3 ? * 6").required(true, i18n).buildTextComponent();
|
||||
@@ -259,6 +259,7 @@ public class MaintenanceWindowLayout extends VerticalLayout {
|
||||
schedule.setValue("");
|
||||
duration.setValue("");
|
||||
timeZone.setValue(getClientTimeZone());
|
||||
scheduleTranslator.setValue(i18n.getMessage(CRON_VALIDATION_ERROR));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -561,6 +561,8 @@ public final class SPUIDefinitions {
|
||||
*/
|
||||
public static final String SP_BUTTON_STATUS_STYLE = "targetStatusBtn";
|
||||
|
||||
public static final String ACTION_HIS_TBL_MAINTENANCE_WINDOW = "Maintenance Window";
|
||||
|
||||
/**
|
||||
* /** Constructor.
|
||||
*/
|
||||
|
||||
@@ -251,6 +251,7 @@ tooltip.check.for.mandatory=Check to make Mandatory
|
||||
tooltip.artifact.icon=Show Artifact Details
|
||||
tooltip.click.to.edit = Click to edit
|
||||
tooltip.metadata.icon = Manage Metadata
|
||||
tooltip.next.maintenancewindow = next on {0}
|
||||
#rollout action
|
||||
tooltip.rollout.run = Run
|
||||
tooltip.rollout.pause = Pause
|
||||
|
||||
Reference in New Issue
Block a user