From 5fd7f3a5b38b4981d7d5c17ed49ae8c673772787 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 21 Apr 2016 14:50:48 +0200 Subject: [PATCH 01/82] Small UI inconsitencies and glitches cleanup - Consitent table muliselect Signed-off-by: Melanie Retter --- .../artifacts/event/SoftwareModuleEvent.java | 4 ++ .../event/SoftwareModuleTypeEvent.java | 2 +- .../smtable/SoftwareModuleTable.java | 12 ++++ .../smtable/SoftwareModuleTableLayout.java | 43 ++++++++++++- .../filterlayout/AbstractFilterButtons.java | 50 ++++++++++++++-- .../table/AbstractNamedVersionTable.java | 42 ++++++++++++- .../ui/common/table/AbstractTable.java | 1 + .../ui/common/table/AbstractTableLayout.java | 20 ++++++- .../dstable/DistributionSetTable.java | 14 +++++ .../dstable/DistributionSetTableLayout.java | 43 +++++++++++++ .../event/DistributionSetTableEvent.java | 60 +++++++++++++++++++ .../event/DistributionSetTypeEvent.java | 15 +---- .../event/SoftwareModuleTableEvent.java | 51 ++++++++++++++++ .../distributions/smtable/SwModuleTable.java | 17 +++++- .../smtable/SwModuleTableLayout.java | 42 +++++++++++++ .../management/dstable/DistributionTable.java | 8 +++ .../dstable/DistributionTableLayout.java | 41 +++++++++++++ .../event/DistributionTableEvent.java | 18 ++++++ .../management/targettable/TargetTable.java | 31 ++++++---- 19 files changed, 477 insertions(+), 37 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java index 95770cb8f..1764f8998 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java @@ -28,6 +28,10 @@ public class SoftwareModuleEvent extends BaseEntityEvent { private SoftwareModuleEventType softwareModuleEventType; + public SoftwareModuleEvent() { + super(null, null); + } + /** * Creates software module event. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java index 88e076775..f1b8deb72 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java @@ -25,7 +25,7 @@ public class SoftwareModuleTypeEvent { * */ public enum SoftwareModuleTypeEnum { - ADD_SOFTWARE_MODULE_TYPE, DELETE_SOFTWARE_MODULE_TYPE, UPDATE_SOFTWARE_MODULE_TYPE + ADD_SOFTWARE_MODULE_TYPE, DELETE_SOFTWARE_MODULE_TYPE, UPDATE_SOFTWARE_MODULE_TYPE, SELECT_ALL } private SoftwareModuleType softwareModuleType; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java index 478438891..11ac5e571 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java @@ -35,6 +35,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.data.Container; import com.vaadin.data.Item; +import com.vaadin.event.Action; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; @@ -211,4 +212,15 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable * i is the id of the table */ -public abstract class AbstractNamedVersionTable extends AbstractTable { +public abstract class AbstractNamedVersionTable extends AbstractTable + implements Handler { private static final long serialVersionUID = 780050712209750719L; + protected ShortcutAction actionSelectAll; + + protected ShortcutAction actionUnSelectAll; + + /** + * Initialize the component. + */ + @Override + protected void init() { + super.init(); + actionSelectAll = new ShortcutAction(i18n.get("action.target.table.selectall")); + actionUnSelectAll = new ShortcutAction(i18n.get("action.target.table.clear")); + setMultiSelect(true); + setSelectable(true); + } + @Override protected List getTableVisibleColumns() { final List columnList = super.getTableVisibleColumns(); @@ -44,4 +64,24 @@ public abstract class AbstractNamedVersionTable extends Table { private static final Logger LOG = LoggerFactory.getLogger(AbstractTable.class); + // TODO MR should be private and use with getter/setter @Autowired protected transient EventBus.SessionEventBus eventBus; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java index b9fa20f03..fa847b4ba 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java @@ -9,8 +9,11 @@ package org.eclipse.hawkbit.ui.common.table; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractTableDetailsLayout; +import org.springframework.beans.factory.annotation.Autowired; +import org.vaadin.spring.events.EventBus; import com.vaadin.event.Action.Handler; +import com.vaadin.event.ShortcutAction; import com.vaadin.ui.Alignment; import com.vaadin.ui.Panel; import com.vaadin.ui.VerticalLayout; @@ -27,6 +30,15 @@ public abstract class AbstractTableLayout extends VerticalLayout { private static final long serialVersionUID = 8611248179949245460L; + /** + * action for the shortcut key ctrl + 'A'. + */ + protected static final ShortcutAction ACTION_CTRL_A = new ShortcutAction("Select All", ShortcutAction.KeyCode.A, + new int[] { ShortcutAction.ModifierKey.CTRL }); + + @Autowired + private transient EventBus.SessionEventBus eventBus; + private AbstractTableHeader tableHeader; private AbstractTable table; @@ -93,12 +105,14 @@ public abstract class AbstractTableLayout extends VerticalLayout { * @return reference of {@link Handler} to handler the short cut keys. * Default is null. */ - protected Handler getShortCutKeysHandler() { - return null; - } + protected abstract Handler getShortCutKeysHandler(); public void setShowFilterButtonVisible(final boolean visible) { tableHeader.setFilterButtonsIconVisible(visible); } + public EventBus.SessionEventBus getEventBus() { + return eventBus; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index 01c242247..56abe5d25 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -31,6 +31,8 @@ import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModule import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.AbstractTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent.DistributionSetComponentEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionsViewAcceptCriteria; import org.eclipse.hawkbit.ui.distributions.event.DragEvent; @@ -55,6 +57,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.data.Container; import com.vaadin.data.Item; +import com.vaadin.event.Action; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; @@ -472,4 +475,15 @@ public class DistributionSetTable extends AbstractNamedVersionTable { + + /** + * DistributionSet table components events. + * + */ + public enum DistributionSetComponentEvent { + SELECT_ALL + } + + private DistributionSetComponentEvent distributionSetComponentEvent; + + /** + * Constructor. + * + * @param eventType + * the event type. + * @param entity + * the entity + */ + public DistributionSetTableEvent(final BaseEntityEventType eventType, final DistributionSet entity) { + super(eventType, entity); + } + + /** + * The component event. + * + * @param DistributionSetTableEvent + * the distributionSet component event. + */ + public DistributionSetTableEvent(final DistributionSetComponentEvent distributionSetComponentEvent) { + super(null, null); + this.distributionSetComponentEvent = distributionSetComponentEvent; + } + + public DistributionSetComponentEvent getDistributionSetComponentEvent() { + return distributionSetComponentEvent; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java index 9cbd1f1bc..798d2a43d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java @@ -30,16 +30,11 @@ public class DistributionSetTypeEvent { private final DistributionSetTypeEnum distributionSetTypeEnum; - private String distributionSetTypeName; - /** * @param distributionSetTypeEnum - * @param distributionSetTypeName */ - public DistributionSetTypeEvent(final DistributionSetTypeEnum distributionSetTypeEnum, - final String distributionSetTypeName) { + public DistributionSetTypeEvent(final DistributionSetTypeEnum distributionSetTypeEnum) { this.distributionSetTypeEnum = distributionSetTypeEnum; - this.distributionSetTypeName = distributionSetTypeName; } /** @@ -52,14 +47,6 @@ public class DistributionSetTypeEvent { this.distributionSetType = distributionSetType; } - public String getDistributionSetTypeName() { - return distributionSetTypeName; - } - - public void setDistributionSetTypeName(final String distributionSetTypeName) { - this.distributionSetTypeName = distributionSetTypeName; - } - public DistributionSetType getDistributionSetType() { return distributionSetType; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java new file mode 100644 index 000000000..d3347d52f --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java @@ -0,0 +1,51 @@ +package org.eclipse.hawkbit.ui.distributions.event; + +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEvent; +import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; + +/** + * + * + * + */ +public class SoftwareModuleTableEvent extends BaseEntityEvent { + + /** + * SoftwareModule table components events. + * + */ + public enum SoftwareModuleComponentEvent { + SELECT_ALL + } + + private SoftwareModuleComponentEvent softwareModuleComponentEvent; + + /** + * Constructor. + * + * @param eventType + * the event type. + * @param entity + * the entity + */ + public SoftwareModuleTableEvent(final BaseEntityEventType eventType, final SoftwareModule entity) { + super(eventType, entity); + } + + /** + * The component event. + * + * @param SoftwareModuleComponentEvent + * the softwareModule component event. + */ + public SoftwareModuleTableEvent(final SoftwareModuleComponentEvent softwareModuleComponentEvent) { + super(null, null); + this.softwareModuleComponentEvent = softwareModuleComponentEvent; + } + + public SoftwareModuleComponentEvent getSoftwareModuleComponentEvent() { + return softwareModuleComponentEvent; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java index eeea33723..d07111858 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTable.java @@ -26,6 +26,8 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionsViewAcceptCriteria; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; +import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent; +import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent.SoftwareModuleComponentEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; @@ -42,6 +44,8 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.data.Container; import com.vaadin.data.Item; +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; @@ -62,7 +66,7 @@ import com.vaadin.ui.Window; */ @SpringComponent @ViewScope -public class SwModuleTable extends AbstractNamedVersionTable { +public class SwModuleTable extends AbstractNamedVersionTable implements Handler { private static final long serialVersionUID = 6785314784507424750L; @@ -388,4 +392,15 @@ public class SwModuleTable extends AbstractNamedVersionTable { + /** + * DistributionSet table components events. + * + */ + public enum DistributionTableComponentEvent { + SELECT_ALL + } + /** * Constructor. * @@ -31,4 +39,14 @@ public class DistributionTableEvent extends BaseEntityEvent { super(eventType, entity); } + /** + * The component event. + * + * @param DistributionSetTableEvent + * the distributionSet component event. + */ + public DistributionTableEvent(final DistributionTableComponentEvent distributionComponentEvent) { + super(null, null); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java index 3b9c18952..7fb2446f0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java @@ -21,7 +21,6 @@ import java.util.stream.Collectors; import org.eclipse.hawkbit.eventbus.event.TargetCreatedEvent; import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent; -import org.eclipse.hawkbit.repository.OffsetBasedPageRequest; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.DistributionSetIdName; @@ -63,7 +62,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition; @@ -353,6 +351,7 @@ public class TargetTable extends AbstractTable implements }; } + // TODO MR private void onTargetDeletedEvent(final List events) { final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); @@ -928,16 +927,24 @@ public class TargetTable extends AbstractTable implements * Select all rows in the table. */ public void selectAll() { - final PageRequest pageRequest = new OffsetBasedPageRequest(0, size(), - new Sort(SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt")); - List targetIdList; - // is custom filter selected - if (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) { - targetIdList = getTargetIdsByCustomFilters(pageRequest); - } else { - targetIdList = getTargetIdsBySimpleFilters(pageRequest); - } - setValue(targetIdList); + // final PageRequest pageRequest = new OffsetBasedPageRequest(0, size(), + // new Sort(SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER, + // "createdAt")); + // List targetIdList; + // // is custom filter selected + // if + // (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) + // { + // targetIdList = getTargetIdsByCustomFilters(pageRequest); + // } else { + // targetIdList = getTargetIdsBySimpleFilters(pageRequest); + // } + // setValue(targetIdList); + + // TODO MR + // As Vaadin Table only returns the current ItemIds which are visible + // you don't need to search explicit for them. + setValue(getItemIds()); } private List getTargetIdsBySimpleFilters(final PageRequest pageRequest) { From 1047219ad2701624e39a555e4264fbdab83d1ace Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 8 Jun 2016 13:02:29 +0200 Subject: [PATCH 02/82] STRG+A for selecting all table rows, remove contextMenu, remove empty lines Signed-off-by: Melanie Retter --- .../smtable/SoftwareModuleTable.java | 11 --- .../smtable/SoftwareModuleTableLayout.java | 3 - .../filterlayout/AbstractFilterButtons.java | 35 +------- .../table/AbstractNamedVersionTable.java | 17 +--- .../ui/common/table/AbstractTable.java | 1 - .../ui/common/table/AbstractTableHeader.java | 4 - .../ui/common/table/AbstractTableLayout.java | 4 - .../disttype/DSTypeFilterButtons.java | 3 - .../dstable/DistributionSetTable.java | 16 ---- .../dstable/DistributionSetTableLayout.java | 5 +- .../distributions/smtable/SwModuleTable.java | 17 +--- .../smtable/SwModuleTableLayout.java | 3 - .../management/dstable/DistributionTable.java | 12 +-- .../dstable/DistributionTableLayout.java | 3 - .../management/targettable/TargetTable.java | 89 +------------------ .../targettable/TargetTableHeader.java | 21 ++--- .../targettable/TargetTableLayout.java | 9 -- .../src/main/resources/messages_de.properties | 4 - 18 files changed, 18 insertions(+), 239 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java index 060aff55b..99fe185e5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java @@ -35,7 +35,6 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.data.Container; import com.vaadin.data.Item; -import com.vaadin.event.Action; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; @@ -213,14 +212,4 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable * i is the id of the table */ -public abstract class AbstractNamedVersionTable extends AbstractTable - implements Handler { +public abstract class AbstractNamedVersionTable extends AbstractTable { private static final long serialVersionUID = 780050712209750719L; - protected ShortcutAction actionSelectAll; - - protected ShortcutAction actionUnSelectAll; - /** * Initialize the component. */ @Override protected void init() { super.init(); - actionSelectAll = new ShortcutAction(i18n.get("action.target.table.selectall")); - actionUnSelectAll = new ShortcutAction(i18n.get("action.target.table.clear")); setMultiSelect(true); setSelectable(true); } @@ -64,11 +54,6 @@ public abstract class AbstractNamedVersionTable extends Table { private static final Logger LOG = LoggerFactory.getLogger(AbstractTable.class); - // TODO MR should be private and use with getter/setter @Autowired protected transient EventBus.SessionEventBus eventBus; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java index b137594f8..3a12ca23e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java @@ -36,10 +36,6 @@ import com.vaadin.ui.VerticalLayout; /** * Parent class for table header. - * - * - * - * */ public abstract class AbstractTableHeader extends VerticalLayout { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java index fa847b4ba..9406dcb93 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java @@ -21,10 +21,6 @@ import com.vaadin.ui.themes.ValoTheme; /** * Parent class for table layout. - * - * - * - * */ public abstract class AbstractTableLayout extends VerticalLayout { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java index 25e081fa0..9b819e1b4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/DSTypeFilterButtons.java @@ -31,9 +31,6 @@ import com.vaadin.spring.annotation.ViewScope; /** * Distribution Set Type filter buttons. - * - * - * */ @SpringComponent @ViewScope diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index e305039fd..a52c0b683 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -30,8 +30,6 @@ import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.table.AbstractNamedVersionTable; import org.eclipse.hawkbit.ui.common.table.AbstractTable; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent.DistributionSetComponentEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionsUIEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionsViewAcceptCriteria; import org.eclipse.hawkbit.ui.distributions.event.DragEvent; @@ -56,7 +54,6 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod; import com.vaadin.data.Container; import com.vaadin.data.Item; -import com.vaadin.event.Action; import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DropHandler; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; @@ -68,7 +65,6 @@ import com.vaadin.ui.UI; /** * Distribution set table. - * */ @SpringComponent @ViewScope @@ -471,18 +467,6 @@ public class DistributionSetTable extends AbstractNamedVersionTable implements Handler { +public class SwModuleTable extends AbstractNamedVersionTable { private static final long serialVersionUID = 6785314784507424750L; @@ -392,15 +388,4 @@ public class SwModuleTable extends AbstractNamedVersionTable implements Handler { +public class TargetTable extends AbstractTable { private static final Logger LOG = LoggerFactory.getLogger(TargetTable.class); private static final String TARGET_PINNED = "targetPinned"; @@ -127,15 +119,10 @@ public class TargetTable extends AbstractTable implements private Button targetPinnedBtn; private Boolean isTargetPinned = Boolean.FALSE; - private ShortcutAction actionSelectAll; - private ShortcutAction actionUnSelectAll; @Override protected void init() { super.init(); - addActionHandler(this); - actionSelectAll = new ShortcutAction(i18n.get("action.target.table.selectall")); - actionUnSelectAll = new ShortcutAction(i18n.get("action.target.table.clear")); setItemDescriptionGenerator(new AssignInstalledDSTooltipGenerator()); } @@ -260,22 +247,6 @@ public class TargetTable extends AbstractTable implements HawkbitCommonUtil.addTargetTableContainerProperties(container); } - @Override - public Action[] getActions(final Object target, final Object sender) { - return new Action[] { actionSelectAll, actionUnSelectAll }; - } - - @Override - public void handleAction(final Action action, final Object sender, final Object target) { - if (actionSelectAll.equals(action)) { - selectAll(); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.SELLECT_ALL)); - } - if (actionUnSelectAll.equals(action)) { - unSelectAll(); - } - } - @Override protected void addCustomGeneratedColumns() { addGeneratedColumn(SPUIDefinitions.TARGET_STATUS_PIN_TOGGLE_ICON, @@ -354,7 +325,6 @@ public class TargetTable extends AbstractTable implements }; } - // TODO MR private void onTargetDeletedEvent(final List events) { final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); @@ -454,7 +424,7 @@ public class TargetTable extends AbstractTable implements pinBtn.setHeightUndefined(); pinBtn.setData(itemId); pinBtn.setId(SPUIComponentIdProvider.TARGET_PIN_ICON + "." + itemId); - pinBtn.addClickListener(event -> addPinClickListener(event)); + pinBtn.addClickListener(this::addPinClickListener); if (isPinned(((TargetIdName) itemId).getControllerId())) { pinBtn.addStyleName(TARGET_PINNED); isTargetPinned = Boolean.TRUE; @@ -931,62 +901,11 @@ public class TargetTable extends AbstractTable implements */ public void selectAll() { - // final PageRequest pageRequest = new OffsetBasedPageRequest(0, size(), - // new Sort(SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER, - // "createdAt")); - // List targetIdList; - // // is custom filter selected - // if - // (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) - // { - // targetIdList = getTargetIdsByCustomFilters(pageRequest); - // } else { - // targetIdList = getTargetIdsBySimpleFilters(pageRequest); - // } - // setValue(targetIdList); - - // TODO MR // As Vaadin Table only returns the current ItemIds which are visible // you don't need to search explicit for them. setValue(getItemIds()); } - private List getTargetIdsBySimpleFilters(final PageRequest pageRequest) { - final Long filterByDistId = managementUIState.getTargetTableFilters().getDistributionSet().isPresent() - ? managementUIState.getTargetTableFilters().getDistributionSet().get().getId() : null; - final List statusList = new ArrayList<>(); - if (isFilteredByStatus()) { - statusList.addAll(managementUIState.getTargetTableFilters().getClickedStatusTargetTags()); - } - final List tagList = new ArrayList<>(); - if (isFilteredByTags()) { - tagList.addAll(managementUIState.getTargetTableFilters().getClickedTargetTags()); - } - String searchText = managementUIState.getTargetTableFilters().getSearchText().isPresent() - ? managementUIState.getTargetTableFilters().getSearchText().get() : null; - if (!Strings.isNullOrEmpty(searchText)) { - searchText = String.format("%%%s%%", searchText); - } - final Boolean noTagSelected = managementUIState.getTargetTableFilters().isNoTagSelected(); - - final String[] tagArray = tagList.toArray(new String[tagList.size()]); - - List targetIdList; - targetIdList = targetManagement.findAllTargetIdsByFilters(pageRequest, statusList, searchText, filterByDistId, - noTagSelected, tagList.toArray(tagArray)); - Collections.reverse(targetIdList); - return targetIdList; - } - - private List getTargetIdsByCustomFilters(final PageRequest pageRequest) { - List targetIdList; - final TargetFilterQuery targetFilterQuery = managementUIState.getTargetTableFilters().getTargetFilterQuery() - .isPresent() ? managementUIState.getTargetTableFilters().getTargetFilterQuery().get() : null; - targetIdList = targetManagement.findAllTargetIdsByTargetFilterQuery(pageRequest, targetFilterQuery); - Collections.reverse(targetIdList); - return targetIdList; - } - /** * Clear all selections in the table. */ @@ -1073,10 +992,6 @@ public class TargetTable extends AbstractTable implements return targetManagement.countTargetsAll(); } - private static TargetIdName getLastSelectedItem(final Set values) { - return Iterables.getLast(values); - } - private boolean isFilteredByStatus() { return !managementUIState.getTargetTableFilters().getClickedStatusTargetTags().isEmpty(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java index b6379729b..5b0aa285a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java @@ -65,9 +65,6 @@ public class TargetTableHeader extends AbstractTableHeader { @Autowired private ManagementUIState managementUIState; - @Autowired - private transient EventBus.SessionEventBus eventBus; - @Autowired private ManagementViewAcceptCriteria managementViewAcceptCriteria; @@ -231,14 +228,14 @@ public class TargetTableHeader extends AbstractTableHeader { @Override protected void showFilterButtonsLayout() { managementUIState.setTargetTagFilterClosed(false); - eventBus.publish(this, ManagementUIEvent.SHOW_TARGET_TAG_LAYOUT); + eventbus.publish(this, ManagementUIEvent.SHOW_TARGET_TAG_LAYOUT); } @Override protected void resetSearchText() { if (managementUIState.getTargetTableFilters().getSearchText().isPresent()) { managementUIState.getTargetTableFilters().setSearchText(null); - eventBus.publish(this, TargetFilterEvent.REMOVE_FILTER_BY_TEXT); + eventbus.publish(this, TargetFilterEvent.REMOVE_FILTER_BY_TEXT); } } @@ -255,13 +252,13 @@ public class TargetTableHeader extends AbstractTableHeader { @Override public void maximizeTable() { managementUIState.setTargetTableMaximized(Boolean.TRUE); - eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.MAXIMIZED,null)); + eventbus.publish(this, new TargetTableEvent(BaseEntityEventType.MAXIMIZED,null)); } @Override public void minimizeTable() { managementUIState.setTargetTableMaximized(Boolean.FALSE); - eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.MINIMIZED,null)); + eventbus.publish(this, new TargetTableEvent(BaseEntityEventType.MINIMIZED,null)); } @Override @@ -277,12 +274,12 @@ public class TargetTableHeader extends AbstractTableHeader { @Override protected void searchBy(final String newSearchText) { managementUIState.getTargetTableFilters().setSearchText(newSearchText); - eventBus.publish(this, TargetFilterEvent.FILTER_BY_TEXT); + eventbus.publish(this, TargetFilterEvent.FILTER_BY_TEXT); } @Override protected void addNewItem(final ClickEvent event) { - eventBus.publish(this, DragEvent.HIDE_DROP_HINT); + eventbus.publish(this, DragEvent.HIDE_DROP_HINT); targetAddUpdateWindow.resetComponents(); final Window addTargetWindow = targetAddUpdateWindow.getWindow(); addTargetWindow.setCaption(i18n.get("caption.add.new.target")); @@ -402,12 +399,12 @@ public class TargetTableHeader extends AbstractTableHeader { getFilterDroppedInfo().addComponent(filteredDistLabel); getFilterDroppedInfo().addComponent(filterLabelClose); getFilterDroppedInfo().setExpandRatio(filteredDistLabel, 1.0f); - eventBus.publish(this, TargetFilterEvent.FILTER_BY_DISTRIBUTION); + eventbus.publish(this, TargetFilterEvent.FILTER_BY_DISTRIBUTION); } private void closeFilterByDistribution() { - eventBus.publish(this, DragEvent.HIDE_DROP_HINT); + eventbus.publish(this, DragEvent.HIDE_DROP_HINT); /* Remove filter by distribution information. */ getFilterDroppedInfo().removeAllComponents(); getFilterDroppedInfo().setSizeUndefined(); @@ -415,7 +412,7 @@ public class TargetTableHeader extends AbstractTableHeader { managementUIState.getTargetTableFilters().setDistributionSet(null); /* Reload the table */ - eventBus.publish(this, TargetFilterEvent.REMOVE_FILTER_BY_DISTRIBUTION); + eventbus.publish(this, TargetFilterEvent.REMOVE_FILTER_BY_DISTRIBUTION); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java index aaf5c6a9f..2bd86868c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java @@ -18,26 +18,17 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; -import com.vaadin.event.ShortcutAction; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; /** * Target table layout. - * - * - * */ @SpringComponent @ViewScope public class TargetTableLayout extends AbstractTableLayout { private static final long serialVersionUID = 2248703121998709112L; - /** - * action for the shortcut key ctrl + 'A'. - */ - private static final ShortcutAction ACTION_CTRL_A = new ShortcutAction("Select All", ShortcutAction.KeyCode.A, - new int[] { ShortcutAction.ModifierKey.CTRL }); @Autowired private transient EventBus.SessionEventBus eventBus; diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index 1ced68c43..d48303ae2 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -299,10 +299,6 @@ message.tag.use.bulk.upload = {0} cannot be deleted .It is in use in targets bul message.bulk.upload.tag.assignment.failed = Tag {0} assignment failed as tag no longer exists message.bulk.upload.tag.assignments.failed= Few tag assignments failed as tags no longer exists -# action info -action.target.table.selectall = Select all (Ctrl+A) -action.target.table.clear = Clear selections - #reused messages soft.module.jvm =Runtime soft.module.application =Application From c2d1e37a16a00433f45e378df6936b676d78140b Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 8 Jun 2016 13:15:38 +0200 Subject: [PATCH 03/82] Add License and JavaDoc Signed-off-by: Melanie Retter --- .../event/SoftwareModuleTableEvent.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java index 70108acef..f722c3a23 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java @@ -1,3 +1,11 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package org.eclipse.hawkbit.ui.distributions.event; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -5,9 +13,7 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEvent; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; /** - * - * - * + * Class which contains the Event when selecting all entries of a table */ public class SoftwareModuleTableEvent extends BaseEntityEvent { @@ -36,7 +42,7 @@ public class SoftwareModuleTableEvent extends BaseEntityEvent { /** * The component event. * - * @param SoftwareModuleComponentEvent + * @param softwareModuleComponentEvent * the softwareModule component event. */ public SoftwareModuleTableEvent(final SoftwareModuleComponentEvent softwareModuleComponentEvent) { From 83dc9471dcaf2d0ba9c057853ca5cf1e8b94698d Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 8 Jun 2016 16:05:48 +0200 Subject: [PATCH 04/82] Enable save button if all mandatory fields are filled (softwareModule) Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 68 +++++++++++++++--- .../CreateUpdateSoftwareTypeLayout.java | 4 +- .../hawkbit/ui/common/CommonDialogWindow.java | 69 ++++++++++++++++++- .../ui/components/SPUIComponentProvider.java | 5 +- .../ui/decorators/SPUIWindowDecorator.java | 7 +- .../CreateUpdateDistSetTypeLayout.java | 3 +- .../AbstractCreateUpdateTagLayout.java | 3 +- .../DistributionAddUpdateWindowLayout.java | 3 +- .../TargetAddUpdateWindowLayout.java | 3 +- .../rollout/AddUpdateRolloutWindowLayout.java | 3 +- 10 files changed, 146 insertions(+), 22 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index ddf229651..0dd85d08b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -9,7 +9,11 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import java.io.Serializable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -29,10 +33,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.spring.events.EventBus; +import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; @@ -129,12 +136,14 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); + nameTextField.addTextChangeListener(this::nameTextFieldChanged); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); + versionTextField.addTextChangeListener(this::versionTextFieldChanged); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, @@ -159,15 +168,40 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY); typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); + typeComboBox.addValueChangeListener(this::typeComboBoxChanged); populateTypeNameCombo(); resetOldValues(); } - /** - * - */ + private void nameTextFieldChanged(final TextChangeEvent event) { + if (StringUtils.isNotBlank(event.getText())) { + window.getRequiredFields().put(nameTextField.getCaption(), Boolean.TRUE); + } else { + window.getRequiredFields().put(nameTextField.getCaption(), Boolean.FALSE); + } + window.checkMandatoryFields(); + } + + private void versionTextFieldChanged(final TextChangeEvent event) { + if (StringUtils.isNotBlank(event.getText())) { + window.getRequiredFields().put(versionTextField.getCaption(), Boolean.TRUE); + } else { + window.getRequiredFields().put(versionTextField.getCaption(), Boolean.FALSE); + } + window.checkMandatoryFields(); + } + + private void typeComboBoxChanged(final ValueChangeEvent event) { + if (event.getProperty().getValue() != null) { + window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.TRUE); + } else { + window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.FALSE); + } + window.checkMandatoryFields(); + } + private void populateTypeNameCombo() { typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer( new BeanQueryFactory(SoftwareModuleTypeBeanQuery.class))); @@ -180,10 +214,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se oldVendorValue = null; } - /** - * Build the window content and get an instance of customDialogWindow - * - */ private void createWindow() { final Label madatoryStarLabel = new Label("*"); @@ -197,7 +227,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addStyleName("lay-color"); final FormLayout formLayout = new FormLayout(); - formLayout.addComponent(mandatoryLabel); + // formLayout.addComponent(mandatoryLabel); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); @@ -208,11 +238,31 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, + getMandatoryFields(formLayout)); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.focus(); } + private Map getMandatoryFields(final FormLayout formLayout) { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + // else if (c instanceof TextField && ((TextField) c).isRequired()) + // { + // requiredFields.put(c.getCaption(), null); + // } else if (c instanceof TextArea && ((TextArea) c).isRequired()) + // { + // requiredFields.put(c.getCaption(), null); + // } + } + return requiredFields; + } + private void addDescriptionTextChangeListener() { descTextArea.addTextChangeListener(event -> window.setSaveButtonEnabled(hasDescriptionChanged(event))); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 85844b917..ad78e09e7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -112,11 +112,13 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout getFormLayout().addComponent(assignOptiongroup); } + // TODO MR requiredFields + @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 247ad0c8f..d14830aa4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -10,29 +10,38 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Map; + import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleBorderWithIcon; +import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; +import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.server.FontAwesome; +import com.vaadin.spring.annotation.SpringComponent; +import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; import com.vaadin.ui.Link; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; +import com.vaadin.ui.themes.ValoTheme; /** - * * Superclass for pop-up-windows including a minimize and close icon in the * upper right corner and a save and cancel button at the bottom. - * */ +@SpringComponent +@ViewScope public class CommonDialogWindow extends Window { private static final long serialVersionUID = -1321949234316858703L; @@ -57,6 +66,11 @@ public class CommonDialogWindow extends Window { private final ClickListener cancelButtonClickListener; + private Map requiredFields; + + @Autowired + private I18N i18n; + /** * Constructor. * @@ -72,7 +86,8 @@ public class CommonDialogWindow extends Window { * the cancelButtonClickListener */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, - final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener) { + final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, + final Map requiredFields) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -80,10 +95,27 @@ public class CommonDialogWindow extends Window { this.helpLink = helpLink; this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; + this.requiredFields = requiredFields; init(); } + /** + * Checks the mandatory fields in the pop-up-window content. If all + * mandatory fields are filled the save button is enabled. Otherwise the + * save button is disabled. + */ + public void checkMandatoryFields() { + + for (final Map.Entry entry : requiredFields.entrySet()) { + if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { + saveButton.setEnabled(false); + return; + } + } + saveButton.setEnabled(true); + } + private final void init() { if (content instanceof AbstractOrderedLayout) { @@ -94,6 +126,9 @@ public class CommonDialogWindow extends Window { if (null != content) { mainLayout.addComponent(content); } + + createMandatoryLabel(); + final HorizontalLayout buttonLayout = createActionButtonsLayout(); mainLayout.addComponent(buttonLayout); mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER); @@ -122,6 +157,17 @@ public class CommonDialogWindow extends Window { return buttonsLayout; } + private void createMandatoryLabel() { + + if (existsMandatoryFieldsInWindowContent()) { + // final Label madatoryLabel = new + // Label(i18n.get("label.mandatory.field")); + final Label madatoryLabel = new Label("* Mandatory Field"); + madatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); + mainLayout.addComponent(madatoryLabel); + } + } + private void createCancelButton() { cancelButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.CANCEL_BUTTON, "Cancel", "", "", true, FontAwesome.TIMES, SPUIButtonStyleBorderWithIcon.class); @@ -140,11 +186,20 @@ public class CommonDialogWindow extends Window { saveButton.setSizeUndefined(); saveButton.addStyleName("default-color"); saveButton.addClickListener(saveButtonClickListener); + saveButton.setEnabled(!existsMandatoryFieldsInWindowContent()); buttonsLayout.addComponent(saveButton); buttonsLayout.setComponentAlignment(saveButton, Alignment.MIDDLE_RIGHT); buttonsLayout.setExpandRatio(saveButton, 1.0F); } + private boolean existsMandatoryFieldsInWindowContent() { + + if (requiredFields != null && requiredFields.size() > 0) { + return true; + } + return false; + } + private void addHelpLink() { if (StringUtils.isEmpty(helpLink)) { @@ -167,4 +222,12 @@ public class CommonDialogWindow extends Window { return buttonsLayout; } + public Map getRequiredFields() { + return requiredFields; + } + + public void setRequiredFields(final Map requiredFields) { + this.requiredFields = requiredFields; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 170ea8dcc..2b743d2a8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -153,9 +153,10 @@ public final class SPUIComponentProvider { */ public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink) { + final ClickListener cancelButtonClickListener, final String helpLink, + final Map requiredFields) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink); + cancelButtonClickListener, helpLink, requiredFields); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index 9f436fd65..f9ce37158 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.ui.decorators; +import java.util.Map; + import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -44,10 +46,11 @@ public final class SPUIWindowDecorator { */ public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink) { + final ClickListener cancelButtonClickListener, final String helpLink, + final Map requiredFields) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener); + cancelButtonClickListener, requiredFields); if (null != id) { window.setId(id); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index a4a9eee35..48cdbfc6a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -610,11 +610,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } } + // TODO MR requiredFields @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index d564accd3..d5f9fef94 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -105,10 +105,11 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; + // TODO MR requiredFields protected void createWindow() { reset(); setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null)); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null)); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 5b5d53524..c0a4dc165 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -504,13 +504,14 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } + // TODO MR requiredFields public CommonDialogWindow getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); populateRequiredComponents(); resetComponents(); addDistributionWindow = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null); + null, null); addDistributionWindow.getButtonsLayout().removeStyleName("actionButtonsMargin"); return addDistributionWindow; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 5a26df572..a5a562c11 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -241,10 +241,11 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } } + // TODO MR requiredFields public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, null); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 2d180f67b..41742d5f7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -157,11 +157,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } + // TODO MR requiredFields public CommonDialogWindow getWindow() { addUpdateRolloutWindow = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView()); + uiProperties.getLinks().getDocumentation().getRolloutView(), null); return addUpdateRolloutWindow; } From bbaa6baa728a7ffae079c3cdd83b277a4ed9692a Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 9 Jun 2016 13:24:40 +0200 Subject: [PATCH 05/82] Improved enable save button functionality when update tag Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 55 +++------ .../CreateUpdateSoftwareTypeLayout.java | 41 ++++++- .../hawkbit/ui/common/CommonDialogWindow.java | 74 +++++++++++- .../ui/components/SPUIComponentProvider.java | 2 + .../CreateUpdateDistSetTypeLayout.java | 49 ++++++-- .../AbstractCreateUpdateTagLayout.java | 71 +++++++++-- .../ui/layouts/CreateUpdateTypeLayout.java | 9 +- .../DistributionAddUpdateWindowLayout.java | 64 ++++++---- ...eateUpdateDistributionTagLayoutWindow.java | 5 + .../TargetAddUpdateWindowLayout.java | 43 +++++-- .../CreateUpdateTargetTagLayoutWindow.java | 4 + .../rollout/AddUpdateRolloutWindowLayout.java | 113 ++++++++++++------ 12 files changed, 384 insertions(+), 146 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 0dd85d08b..309c111ea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -13,7 +13,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -73,8 +72,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se @Autowired private transient EntityFactory entityFactory; - private Label mandatoryLabel; - private TextField nameTextField; private TextField versionTextField; @@ -136,14 +133,14 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - nameTextField.addTextChangeListener(this::nameTextFieldChanged); + nameTextField.addTextChangeListener(this::listenerNameTextFieldChanged); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); - versionTextField.addTextChangeListener(this::versionTextFieldChanged); + versionTextField.addTextChangeListener(this::listenerVersionTextFieldChanged); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, @@ -157,49 +154,29 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addDescriptionTextChangeListener(); addVendorTextChangeListener(); - /* Label for mandatory symbol */ - mandatoryLabel = new Label(i18n.get("label.mandatory.field")); - mandatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - mandatoryLabel.addStyleName(ValoTheme.LABEL_SMALL); - typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); typeComboBox.setId(SPUIComponentIdProvider.SW_MODULE_TYPE); typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY); typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); - typeComboBox.addValueChangeListener(this::typeComboBoxChanged); + typeComboBox.addValueChangeListener(this::listenerTypeComboBoxChanged); populateTypeNameCombo(); resetOldValues(); } - private void nameTextFieldChanged(final TextChangeEvent event) { - if (StringUtils.isNotBlank(event.getText())) { - window.getRequiredFields().put(nameTextField.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(nameTextField.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, nameTextField); } - private void versionTextFieldChanged(final TextChangeEvent event) { - if (StringUtils.isNotBlank(event.getText())) { - window.getRequiredFields().put(versionTextField.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(versionTextField.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerVersionTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, versionTextField); } - private void typeComboBoxChanged(final ValueChangeEvent event) { - if (event.getProperty().getValue() != null) { - window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.TRUE); - } else { - window.getRequiredFields().put(typeComboBox.getCaption(), Boolean.FALSE); - } - window.checkMandatoryFields(); + private void listenerTypeComboBoxChanged(final ValueChangeEvent event) { + window.checkMandatoryComboBox(event, typeComboBox); } private void populateTypeNameCombo() { @@ -212,6 +189,10 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void resetOldValues() { oldDescriptionValue = null; oldVendorValue = null; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void createWindow() { @@ -227,7 +208,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addStyleName("lay-color"); final FormLayout formLayout = new FormLayout(); - // formLayout.addComponent(mandatoryLabel); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); @@ -252,13 +232,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { requiredFields.put(c.getCaption(), null); } - // else if (c instanceof TextField && ((TextField) c).isRequired()) - // { - // requiredFields.put(c.getCaption(), null); - // } else if (c instanceof TextArea && ((TextArea) c).isRequired()) - // { - // requiredFields.put(c.getCaption(), null); - // } } return requiredFields; } @@ -347,6 +320,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void closeThisWindow() { window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -383,6 +357,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se } else { addNewBaseSoftware(); } + window.setSaveButtonEnabled(false); } private boolean hasDescriptionChanged(final TextChangeEvent event) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index ad78e09e7..7473d5509 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -9,7 +9,10 @@ package org.eclipse.hawkbit.ui.artifacts.smtype; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; @@ -31,11 +34,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.components.colorpicker.ColorChangeListener; @@ -69,7 +75,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void addListeners() { super.addListeners(); - optiongroup.addValueChangeListener(this::createOptionValueChanged); + optiongroup.addValueChangeListener(this::optionValueChanged); } @Override @@ -86,11 +92,13 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY); + typeKey.addTextChangeListener(this::typeKeyTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", @@ -103,6 +111,14 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout singleMultiOptionGroup(); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, tagName); + } + + private void typeKeyTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, typeKey); + } + @Override protected void buildLayout() { @@ -112,13 +128,23 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout getFormLayout().addComponent(assignOptiongroup); } - // TODO MR requiredFields - @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = getFormLayout().iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** @@ -128,9 +154,9 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout * ValueChangeEvent */ @Override - protected void createOptionValueChanged(final ValueChangeEvent event) { + protected void optionValueChanged(final ValueChangeEvent event) { - super.createOptionValueChanged(event); + super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { assignOptiongroup.setEnabled(false); @@ -172,6 +198,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout .findSoftwareModuleTypeByName(targetTagSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); + setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); if (selectedTypeTag.getMaxAssignments() == Integer.MAX_VALUE) { assignOptiongroup.setValue(multiAssignStr); @@ -201,6 +228,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void save(final ClickEvent event) { if (!mandatoryValuesPresent()) { + window.setSaveButtonEnabled(false); return; } @@ -216,6 +244,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout updateSWModuleType(existingSMTypeByName); } + window.setSaveButtonEnabled(false); } private void createNewSWModuleType() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index d14830aa4..7b5df4a8f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; +import java.io.Serializable; import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -20,11 +21,14 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.springframework.beans.factory.annotation.Autowired; +import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; -import com.vaadin.spring.annotation.SpringComponent; -import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.AbstractOrderedLayout; +import com.vaadin.ui.AbstractSelect; +import com.vaadin.ui.AbstractTextField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; @@ -40,9 +44,7 @@ import com.vaadin.ui.themes.ValoTheme; * Superclass for pop-up-windows including a minimize and close icon in the * upper right corner and a save and cancel button at the bottom. */ -@SpringComponent -@ViewScope -public class CommonDialogWindow extends Window { +public class CommonDialogWindow extends Window implements Serializable { private static final long serialVersionUID = -1321949234316858703L; @@ -100,12 +102,38 @@ public class CommonDialogWindow extends Window { init(); } + public void checkMandatoryTextField(final TextChangeEvent event, final AbstractTextField textfield) { + + if (StringUtils.isNotBlank(event.getText())) { + getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + } else { + getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + } + checkMandatoryFields(); + } + + public void checkMandatoryComboBox(final ValueChangeEvent event, final AbstractSelect select) { + + if (event.getProperty().getValue() != null) { + if (StringUtils.isNotBlank(select.getCaption())) { + getRequiredFields().put(select.getCaption(), Boolean.TRUE); + } + getRequiredFields().put(select.getId(), Boolean.TRUE); + } else { + if (StringUtils.isNotBlank(select.getCaption())) { + getRequiredFields().put(select.getCaption(), Boolean.FALSE); + } + getRequiredFields().put(select.getId(), Boolean.FALSE); + } + checkMandatoryFields(); + } + /** * Checks the mandatory fields in the pop-up-window content. If all * mandatory fields are filled the save button is enabled. Otherwise the * save button is disabled. */ - public void checkMandatoryFields() { + private void checkMandatoryFields() { for (final Map.Entry entry : requiredFields.entrySet()) { if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { @@ -116,6 +144,40 @@ public class CommonDialogWindow extends Window { saveButton.setEnabled(true); } + public void updateRequiredFields(final String fieldId, final Boolean filled) { + + getRequiredFields().put(fieldId, Boolean.TRUE); + checkMandatoryFields(); + } + + public void checkChanges(final String newText, final String oldText) { + + if ((StringUtils.isNotBlank(newText) && !newText.equals(oldText)) + || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText))) { + saveButton.setEnabled(true); + } else { + saveButton.setEnabled(false); + } + } + + public void checkColorChange(final Color newColor, final Color oldColor) { + + if (newColor.equals(oldColor)) { + setSaveButtonEnabled(false); + } else { + setSaveButtonEnabled(true); + } + } + + public void resetRequiredFieldsValues() { + // Reset mandatory fields are filled marker + if (getRequiredFields() != null) { + for (final Map.Entry entry : getRequiredFields().entrySet()) { + entry.setValue(null); + } + } + } + private final void init() { if (content instanceof AbstractOrderedLayout) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 2b743d2a8..3ba71fce5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -205,6 +205,8 @@ public final class SPUIComponentProvider { /** * Get Label UI component. * * + * @param caption + * set the caption of the textArea * @param style * set style * @param styleName diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 48cdbfc6a..a04136a48 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -8,7 +8,10 @@ */ package org.eclipse.hawkbit.ui.distributions.disttype; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -37,9 +40,11 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.IndexedContainer; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -94,11 +99,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); + typeKey.addTextChangeListener(this::listenerTypeKeyTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", @@ -109,6 +116,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setNullRepresentation(""); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, tagName); + } + + private void listenerTypeKeyTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, typeKey); + } + @Override protected void buildLayout() { @@ -247,10 +263,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void addSMType() { final Set selectedIds = (Set) sourceTable.getValue(); - if (null != selectedIds && !selectedIds.isEmpty()) { + if (selectedIds != null && !selectedIds.isEmpty()) { for (final Long id : selectedIds) { addTargetTableData(id); } + + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); } } @@ -264,6 +282,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout selectedTable.removeItem(id); } } + if (selectedIds == null || selectedIds.isEmpty()) { + window.updateRequiredFields(selectedTable.getId(), Boolean.FALSE); + } } @SuppressWarnings("unchecked") @@ -484,9 +505,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout * ValueChangeEvent */ @Override - protected void createOptionValueChanged(final ValueChangeEvent event) { + protected void optionValueChanged(final ValueChangeEvent event) { - super.createOptionValueChanged(event); + super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { selectedTable.getContainerDataSource().removeAllItems(); @@ -551,18 +572,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout final DistributionSetType selectedTypeTag = fetchDistributionSetType(distSetTypeSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); + setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) { distTypeSelectLayout.setEnabled(true); selectedTable.setEnabled(true); - window.setSaveButtonEnabled(true); } else { uiNotification.displayValidationError( selectedTypeTag.getName() + " " + i18n.get("message.error.dist.set.type.update")); distTypeSelectLayout.setEnabled(false); selectedTable.setEnabled(false); - window.setSaveButtonEnabled(false); } for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) { addTargetTableforUpdate(swModuleType, false); @@ -607,15 +627,30 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { updateDistributionSetType(existingDistTypeByKey); } + window.setSaveButtonEnabled(false); } } - // TODO MR requiredFields @Override public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = getFormLayout().iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + // Selected SoftwareModulesType + requiredFields.put(selectedTable.getId(), null); + + return requiredFields; } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index d5f9fef94..f8fb5c3e0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -8,6 +8,10 @@ */ package org.eclipse.hawkbit.ui.layouts; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.SpPermissionChecker; @@ -25,7 +29,6 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -33,11 +36,14 @@ import org.vaadin.spring.events.EventBus; import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.ComboBox; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; @@ -87,7 +93,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected CommonDialogWindow window; protected Label colorLabel; - protected Label madatoryLabel; protected TextField tagName; protected TextArea tagDesc; protected Button tagColorPreviewBtn; @@ -105,11 +110,25 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; - // TODO MR requiredFields + private Color selectedColorOriginal; + private String tagDescOriginal; + protected void createWindow() { reset(); setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, null)); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields())); + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** @@ -158,7 +177,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent createTagStr = i18n.get("label.create.tag"); updateTagStr = i18n.get("label.update.tag"); comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag"), null); - madatoryLabel = getMandatoryLabel(); colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag.color"), null); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); @@ -166,6 +184,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_TARGET_TAG_NAME); + tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), @@ -174,6 +193,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); + tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); tagNameComboBox = SPUIComponentProvider.getComboBox(null, "", "", null, null, false, "", i18n.get("label.combobox.tag")); @@ -186,6 +206,16 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagColorPreviewBtn.setStyleName(TAG_DYNAMIC_STYLE); } + private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, tagName); + } + + private void listenerTagDescTextAreaChanged(final TextChangeEvent event) { + + window.checkChanges(event.getText(), tagDescOriginal); + } + protected void buildLayout() { mainLayout = new GridLayout(3, 2); @@ -201,7 +231,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent formLayout.addComponent(optiongroup); formLayout.addComponent(comboLayout); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(tagName); formLayout.addComponent(tagDesc); formLayout.addStyleName("form-lastrow"); @@ -269,12 +298,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } } - protected Label getMandatoryLabel() { - final Label label = new Label(i18n.get("label.mandatory.field")); - label.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - return label; - } - private void tagNameChosen(final ValueChangeEvent event) { final String tagSelected = (String) event.getProperty().getValue(); if (null != tagSelected) { @@ -319,6 +342,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } + window.setSaveButtonEnabled(false); // close the color picker layout tagPreviewBtnClicked = false; // reset the selected color - Set default color @@ -347,6 +371,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } /** @@ -434,11 +462,14 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent createDynamicStyleForComponents(tagName, tagDesc, colorPickedPreview); colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } + + window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); } protected void closeWindow() { window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -643,4 +674,20 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent return formLayout; } + public Color getSelectedColorOriginal() { + return selectedColorOriginal; + } + + public void setSelectedColorOriginal(final Color selectedColorOriginal) { + this.selectedColorOriginal = selectedColorOriginal; + } + + public String getTagDescOriginal() { + return tagDescOriginal; + } + + public void setTagDescOriginal(final String tagDescOriginal) { + this.tagDescOriginal = tagDescOriginal; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 1987d6053..c67d35321 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -52,7 +52,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { @Override protected void addListeners() { super.addListeners(); - optiongroup.addValueChangeListener(this::createOptionValueChanged); + optiongroup.addValueChangeListener(this::optionValueChanged); } @Override @@ -61,7 +61,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createTypeStr = i18n.get("label.create.type"); updateTypeStr = i18n.get("label.update.type"); comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type"), null); - madatoryLabel = getMandatoryLabel(); colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type.color"), null); colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE); @@ -137,7 +136,8 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { * @param event * ValueChangeEvent */ - protected void createOptionValueChanged(final ValueChangeEvent event) { + @Override + protected void optionValueChanged(final ValueChangeEvent event) { if (updateTypeStr.equals(event.getProperty().getValue())) { tagName.clear(); @@ -158,6 +158,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } + window.setSaveButtonEnabled(false); restoreComponentStyles(); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); getColorPickerLayout().getSelPreview() @@ -236,12 +237,14 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); createDynamicStyleForComponents(tagName, typeKey, tagDesc, ColorPickerConstants.DEFAULT_COLOR); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { getColorPickerLayout().setSelectedColor(ColorPickerHelper.rgbToColorConverter(color)); getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelectedColor()); createDynamicStyleForComponents(tagName, typeKey, tagDesc, color); getPreviewButtonColor(color); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(color)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index c0a4dc165..82cf2390c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; @@ -49,12 +50,12 @@ import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.AbstractField; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; @@ -92,13 +93,12 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private TextField distNameTextField; private TextField distVersionTextField; - private Label madatoryLabel; private TextArea descTextArea; private CheckBox reqMigStepCheckbox; private ComboBox distsetTypeNameComboBox; private boolean editDistribution = Boolean.FALSE; private Long editDistId; - private CommonDialogWindow addDistributionWindow; + private CommonDialogWindow window; private String originalDistName; private String originalDistVersion; private String originalDistDescription; @@ -132,7 +132,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { setSizeUndefined(); formLayout = new FormLayout(); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(distsetTypeNameComboBox); formLayout.addComponent(distNameTextField); formLayout.addComponent(distVersionTextField); @@ -152,12 +151,14 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distNameTextField.setId(SPUIComponentIdProvider.DIST_ADD_NAME); distNameTextField.setNullRepresentation(""); + distNameTextField.addTextChangeListener(this::listenerDistNameTextFieldChanged); distVersionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distVersionTextField.setId(SPUIComponentIdProvider.DIST_ADD_VERSION); distVersionTextField.setNullRepresentation(""); + distVersionTextField.addTextChangeListener(this::listenerDistVersionTextFieldChanged); distsetTypeNameComboBox = SPUIComponentProvider.getComboBox(i18n.get("label.combobox.type"), "", "", null, "", false, "", i18n.get("label.combobox.type")); @@ -171,16 +172,20 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC); descTextArea.setNullRepresentation(""); - /* Label for mandatory symbol */ - madatoryLabel = new Label(i18n.get("label.mandatory.field")); - madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"), "dist-checkbox-style", null, false, ""); reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL); reqMigStepCheckbox.setId(SPUIComponentIdProvider.DIST_ADD_MIGRATION_CHECK); } + private void listenerDistNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, distNameTextField); + } + + private void listenerDistVersionTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, distVersionTextField); + } + /** * Get the LazyQueryContainer instance for DistributionSetTypes. * @@ -201,7 +206,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void enableSaveButton() { - addDistributionWindow.setSaveButtonEnabled(true); + window.setSaveButtonEnabled(true); } private DistributionSetType getDefaultDistributionSetType() { @@ -210,17 +215,16 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void disableSaveButton() { - addDistributionWindow.setSaveButtonEnabled(false); + window.setSaveButtonEnabled(false); } private void saveDistribution() { - /* add new or update target */ if (editDistribution) { updateDistribution(); } else { addNewDistribution(); } - + window.setSaveButtonEnabled(false); } /** @@ -298,8 +302,9 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { * Close window. */ private void closeThisWindow() { - addDistributionWindow.close(); - UI.getCurrent().removeWindow(addDistributionWindow); + window.close(); + UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } /** @@ -398,11 +403,15 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); descTextArea.clear(); reqMigStepCheckbox.clear(); - if (addDistributionWindow != null) { - addDistributionWindow.setSaveButtonEnabled(true); + if (window != null) { + window.setSaveButtonEnabled(true); } removeListeners(); changedComponents.clear(); + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void populateRequiredComponents() { @@ -482,7 +491,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { public void populateValuesOfDistribution(final Long editDistId) { this.editDistId = editDistId; editDistribution = Boolean.TRUE; - addDistributionWindow.setSaveButtonEnabled(false); + window.setSaveButtonEnabled(false); final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); if (distSet != null) { distNameTextField.setValue(distSet.getName()); @@ -504,17 +513,28 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } - // TODO MR requiredFields public CommonDialogWindow getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); populateRequiredComponents(); resetComponents(); - addDistributionWindow = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, + window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, null); - addDistributionWindow.getButtonsLayout().removeStyleName("actionButtonsMargin"); + null, getMandatoryFields()); + window.getButtonsLayout().removeStyleName("actionButtonsMargin"); - return addDistributionWindow; + return window; + } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 0d4da54e8..3bee67345 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -98,6 +98,7 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat updateExistingTag(existingDistTag); } } + window.setSaveButtonEnabled(false); } /** @@ -159,11 +160,14 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat final DistributionSetTag selectedDistTag = tagManagement.findDistributionSetTag(distTagSelected); if (null != selectedDistTag) { tagDesc.setValue(selectedDistTag.getDescription()); + setTagDescOriginal(selectedDistTag.getDescription()); if (null == selectedDistTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { setTagColor(ColorPickerHelper.rgbToColorConverter(selectedDistTag.getColour()), selectedDistTag.getColour()); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(selectedDistTag.getColour())); } } } @@ -181,4 +185,5 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat setOptionGroupDefaultValue(permChecker.hasCreateDistributionPermission(), permChecker.hasUpdateDistributionPermission()); } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index a5a562c11..e5d65295b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -8,9 +8,13 @@ */ package org.eclipse.hawkbit.ui.management.targettable; +import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.Target; @@ -35,6 +39,8 @@ import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; @@ -73,7 +79,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private TextField controllerIDTextField; private TextField nameTextField; private TextArea descTextArea; - private Label madatoryLabel; private boolean editTarget = Boolean.FALSE; private String controllerId; private FormLayout formLayout; @@ -100,6 +105,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField = SPUIComponentProvider.getTextField( i18n.get("prompt.target.id"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID); + controllerIDTextField.addTextChangeListener(this::listenerControllerIDTextFieldChanged); /* Textfield for target name */ nameTextField = SPUIComponentProvider.getTextField( i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, false, null, @@ -111,10 +117,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC); descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); - - /* Label for mandatory symbol */ - madatoryLabel = new Label(i18n.get("label.mandatory.field")); - madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); + } + + private void listenerControllerIDTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, controllerIDTextField); } private void buildLayout() { @@ -125,14 +131,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { */ formLayout = new FormLayout(); - formLayout.addComponent(madatoryLabel); formLayout.addComponent(controllerIDTextField); formLayout.addComponent(nameTextField); formLayout.addComponent(descTextArea); - if (Boolean.TRUE.equals(editTarget)) { - madatoryLabel.setVisible(Boolean.FALSE); - } nameTextField.focus(); } @@ -211,6 +213,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } else { addNewTarget(); } + window.setSaveButtonEnabled(false); } private void discardTargetListner() { @@ -241,13 +244,24 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } } - // TODO MR requiredFields public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields()); return window; } + + private Map getMandatoryFields() { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getCaption(), null); + } + } + return requiredFields; + } /** * clear all fields of Target Edit Window. @@ -261,12 +275,17 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField.clear(); descTextArea.clear(); editTarget = Boolean.FALSE; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void closeThisWindow() { editTarget = Boolean.FALSE; window.close(); UI.getCurrent().removeWindow(window); + window.setSaveButtonEnabled(false); } private void setTargetValues(final Target target, final String name, final String description) { @@ -287,7 +306,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private boolean duplicateCheck(final String newControlllerId) { final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); if (existingTarget != null) { - uINotification.displayValidationError(i18n.get("message.target.duplicate.check")); + uINotification.displayValidationError(i18n.get("message.target.duplicate.check", new Object[] {newControlllerId})); return false; } else { return true; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index a7d612f72..81c0c72ae 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -91,11 +91,14 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa final TargetTag selectedTargetTag = tagManagement.findTargetTag(targetTagSelected); if (null != selectedTargetTag) { tagDesc.setValue(selectedTargetTag.getDescription()); + setTagDescOriginal(selectedTargetTag.getDescription()); if (null == selectedTargetTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); + setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); } else { setTagColor(ColorPickerHelper.rgbToColorConverter(selectedTargetTag.getColour()), selectedTargetTag.getColour()); + setSelectedColorOriginal(ColorPickerHelper.rgbToColorConverter(selectedTargetTag.getColour())); } } } @@ -112,6 +115,7 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa updateExistingTag(existingTag); } } + window.setSaveButtonEnabled(false); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 41742d5f7..1226ec5fb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -10,7 +10,9 @@ package org.eclipse.hawkbit.ui.rollout.rollout; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; @@ -58,6 +60,7 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Validator; import com.vaadin.data.validator.IntegerRangeValidator; import com.vaadin.data.validator.RegexpValidator; +import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.ComboBox; @@ -115,8 +118,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Autowired private transient EventBus.SessionEventBus eventBus; - private Label mandatoryLabel; - private TextField rolloutName; private ComboBox distributionSet; @@ -135,7 +136,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private OptionGroup errorThresholdOptionGroup; - private CommonDialogWindow addUpdateRolloutWindow; + private CommonDialogWindow window; private Boolean editRolloutEnabled; @@ -157,13 +158,25 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } - // TODO MR requiredFields public CommonDialogWindow getWindow() { - addUpdateRolloutWindow = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, + window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView(), null); - return addUpdateRolloutWindow; + uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields()); + return window; + } + + private Map getMandatoryFields() { + + final Map requiredFields = new HashMap<>(); + requiredFields.put(rolloutName.getId(), null); + requiredFields.put(distributionSet.getId(), null); + requiredFields.put(targetFilterQueryCombo.getId(), null); + requiredFields.put(noOfGroups.getId(), null); + requiredFields.put(triggerThreshold.getId(), null); + requiredFields.put(errorThreshold.getId(), null); + + return requiredFields; } /** @@ -187,6 +200,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { actionTypeOptionGroupLayout.selectDefaultOption(); totalTargetsCount = 0L; rolloutForEdit = null; + + if (window != null) { + window.resetRequiredFieldsValues(); + } } private void resetFields() { @@ -208,26 +225,25 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { setRows(9); setColumns(3); - addComponent(mandatoryLabel, 1, 0, 2, 0); - addComponent(getLabel("textfield.name"), 0, 1); - addComponent(rolloutName, 1, 1); - addComponent(getLabel("prompt.distribution.set"), 0, 2); - addComponent(distributionSet, 1, 2); - addComponent(getLabel("prompt.target.filter"), 0, 3); - addComponent(targetFilterQueryCombo, 1, 3); - addComponent(totalTargetsLabel, 2, 3); - addComponent(getLabel("prompt.number.of.groups"), 0, 4); - addComponent(noOfGroups, 1, 4); - addComponent(groupSizeLabel, 2, 4); - addComponent(getLabel("prompt.tigger.threshold"), 0, 5); - addComponent(triggerThreshold, 1, 5); - addComponent(getPercentHintLabel(), 2, 5); - addComponent(getLabel("prompt.error.threshold"), 0, 6); - addComponent(errorThreshold, 1, 6); - addComponent(errorThresholdOptionGroup, 2, 6); - addComponent(getLabel("textfield.description"), 0, 7); - addComponent(description, 1, 7, 2, 7); - addComponent(actionTypeOptionGroupLayout, 0, 8, 2, 8); + addComponent(getLabel("textfield.name"), 0, 0); + addComponent(rolloutName, 1, 0); + addComponent(getLabel("prompt.distribution.set"), 0, 1); + addComponent(distributionSet, 1, 1); + addComponent(getLabel("prompt.target.filter"), 0, 2); + addComponent(targetFilterQueryCombo, 1, 2); + addComponent(totalTargetsLabel, 2, 2); + addComponent(getLabel("prompt.number.of.groups"), 0, 3); + addComponent(noOfGroups, 1, 3); + addComponent(groupSizeLabel, 2, 3); + addComponent(getLabel("prompt.tigger.threshold"), 0, 4); + addComponent(triggerThreshold, 1, 4); + addComponent(getPercentHintLabel(), 2, 4); + addComponent(getLabel("prompt.error.threshold"), 0, 5); + addComponent(errorThreshold, 1, 5); + addComponent(errorThresholdOptionGroup, 2, 5); + addComponent(getLabel("textfield.description"), 0, 6); + addComponent(description, 1, 6, 2, 6); + addComponent(actionTypeOptionGroupLayout, 0, 7, 2, 7); rolloutName.focus(); } @@ -249,7 +265,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void createRequiredComponents() { - mandatoryLabel = createMandatoryLabel(); rolloutName = createRolloutNameField(); distributionSet = createDistributionSetCombo(); populateDistributionSet(); @@ -308,11 +323,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL); errorThresoldOptions.addStyleName(SPUIStyleDefinitions.ROLLOUT_OPTION_GROUP); errorThresoldOptions.setSizeUndefined(); - errorThresoldOptions.addValueChangeListener(this::onErrorThresoldOptionChange); + errorThresoldOptions.addValueChangeListener(this::listenerOnErrorThresoldOptionChange); return errorThresoldOptions; } - private void onErrorThresoldOptionChange(final ValueChangeEvent event) { + private void listenerOnErrorThresoldOptionChange(final ValueChangeEvent event) { errorThreshold.clear(); errorThreshold.removeAllValidators(); if (event.getProperty().getValue().equals(ERRORTHRESOLDOPTIONS.COUNT.getValue())) { @@ -331,11 +346,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); targetFilter.setId(SPUIComponentIdProvider.ROLLOUT_TARGET_FILTER_COMBO_ID); targetFilter.setSizeUndefined(); - targetFilter.addValueChangeListener(event -> onTargetFilterChange()); + targetFilter.addValueChangeListener(this::onTargetFilterChange); return targetFilter; } - private void onTargetFilterChange() { + private void onTargetFilterChange(final ValueChangeEvent event) { final String filterQueryString = getTargetFilterQuery(); if (!Strings.isNullOrEmpty(filterQueryString)) { totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(filterQueryString); @@ -346,6 +361,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsLabel.setVisible(false); } onGroupNumberChange(); + + window.checkMandatoryComboBox(event, targetFilterQueryCombo); } private String getTotalTargetMessage() { @@ -490,8 +507,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void closeThisWindow() { - addUpdateRolloutWindow.close(); - UI.getCurrent().removeWindow(addUpdateRolloutWindow); + window.close(); + UI.getCurrent().removeWindow(window); } private boolean mandatoryCheck() { @@ -560,18 +577,29 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID); errorField.setMaxLength(7); errorField.setSizeUndefined(); + errorField.addTextChangeListener(this::listenerErrorThresholdTextFieldChanged); return errorField; } + private void listenerErrorThresholdTextFieldChanged(final TextChangeEvent event) { + + window.checkMandatoryTextField(event, errorThreshold); + } + private TextField createTriggerThresold() { final TextField thresholdField = getTextfield("prompt.tigger.threshold"); thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); thresholdField.addValidator(new ThresholdFieldValidator()); thresholdField.setSizeUndefined(); thresholdField.setMaxLength(3); + thresholdField.addTextChangeListener(this::listenerTriggerThresholdTextFieldChanged); return thresholdField; } + private void listenerTriggerThresholdTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, triggerThreshold); + } + private TextField createNoOfGroupsField() { final TextField noOfGroupsField = getTextfield("prompt.number.of.groups"); noOfGroupsField.setId(SPUIComponentIdProvider.ROLLOUT_NO_OF_GROUPS_ID); @@ -579,9 +607,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); noOfGroupsField.addValueChangeListener(evevt -> onGroupNumberChange()); + noOfGroupsField.addTextChangeListener(this::listenerNoOfGroupsTextFieldChanged); return noOfGroupsField; } + private void listenerNoOfGroupsTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, noOfGroups); + } + private void onGroupNumberChange() { if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) { groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize()))); @@ -599,9 +632,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); dsSet.setId(SPUIComponentIdProvider.ROLLOUT_DS_ID); dsSet.setSizeUndefined(); + dsSet.addValueChangeListener(this::listenerDistributionSetChanged); return dsSet; } + private void listenerDistributionSetChanged(final ValueChangeEvent event) { + window.checkMandatoryComboBox(event, distributionSet); + } + private void populateDistributionSet() { final Container container = createDsComboContainer(); distributionSet.setContainerDataSource(container); @@ -620,13 +658,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { final TextField rolloutNameField = getTextfield("textfield.name"); rolloutNameField.setId(SPUIComponentIdProvider.ROLLOUT_NAME_FIELD_ID); rolloutNameField.setSizeUndefined(); + rolloutNameField.addTextChangeListener(this::listenerRolloutNameTextFieldChanged); return rolloutNameField; } - private Label createMandatoryLabel() { - final Label madatoryLbl = new Label(i18n.get("label.mandatory.field")); - madatoryLbl.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL); - return madatoryLbl; + private void listenerRolloutNameTextFieldChanged(final TextChangeEvent event) { + window.checkMandatoryTextField(event, rolloutName); } private String getRolloutName() { From d5e591a4a6f38d73e3e1efd23714b95789227837 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Fri, 10 Jun 2016 08:37:56 +0200 Subject: [PATCH 06/82] Configurable basic scenario. Signed-off-by: Kai Zimmermann --- .../builder/DistributionSetBuilder.java | 32 +++-- .../builder/DistributionSetTypeBuilder.java | 10 +- .../builder/SoftwareModuleBuilder.java | 10 +- .../builder/SoftwareModuleTypeBuilder.java | 10 +- .../resource/builder/TargetBuilder.java | 53 +++++-- .../hawkbit/mgmt/client/Application.java | 10 +- .../client/ClientConfigurationProperties.java | 76 ++++++++++ .../scenarios/ConfigurableScenario.java | 92 ++++++++++++ .../CreateStartedRolloutExample.java | 2 +- .../GettingStartedDefaultScenario.java | 135 ------------------ .../src/main/resources/application.properties | 11 +- 11 files changed, 264 insertions(+), 177 deletions(-) create mode 100644 examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java delete mode 100644 examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java index 1e58b8415..a51d96d88 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java @@ -84,32 +84,48 @@ public class DistributionSetBuilder { * @return a single entry list of {@link MgmtDistributionSetRequestBodyPost} */ public List build() { - return Lists.newArrayList(doBuild(name)); + return Lists.newArrayList(doBuild("")); } /** * Builds a list of multiple {@link MgmtDistributionSetRequestBodyPost} to * create multiple distribution sets at once. An increasing number will be - * added to the name of the distribution set. The version and type will - * remain the same. + * used for version of the distribution set. The name and type will remain + * the same. * * @param count * the amount of distribution sets body which should be created * @return a list of {@link MgmtDistributionSetRequestBodyPost} */ public List buildAsList(final int count) { + return buildAsList(0, count); + } + + /** + * Builds a list of multiple {@link MgmtDistributionSetRequestBodyPost} to + * create multiple distribution sets at once. An increasing number will be + * used for version of the distribution set starting from given offset. The + * name and type will remain the same. + * + * @param count + * the amount of distribution sets body which should be created + * @param offset + * for for index start + * @return a list of {@link MgmtDistributionSetRequestBodyPost} + */ + public List buildAsList(final int offset, final int count) { final ArrayList bodyList = Lists.newArrayList(); - for (int index = 0; index < count; index++) { - bodyList.add(doBuild(name + index)); + for (int index = offset; index < count + offset; index++) { + bodyList.add(doBuild(String.valueOf(index))); } return bodyList; } - private MgmtDistributionSetRequestBodyPost doBuild(final String prefixName) { + private MgmtDistributionSetRequestBodyPost doBuild(final String suffix) { final MgmtDistributionSetRequestBodyPost body = new MgmtDistributionSetRequestBodyPost(); - body.setName(prefixName); - body.setVersion(version); + body.setName(name); + body.setVersion(version + suffix); body.setType(type); body.setDescription(description); body.setModules(modules); diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java index 1ce2ff270..028060f37 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java @@ -101,7 +101,7 @@ public class DistributionSetTypeBuilder { * {@link MgmtDistributionSetTypeRequestBodyPost} */ public List build() { - return Lists.newArrayList(doBuild(name, key)); + return Lists.newArrayList(doBuild("")); } /** @@ -118,16 +118,16 @@ public class DistributionSetTypeBuilder { public List buildAsList(final int count) { final ArrayList bodyList = Lists.newArrayList(); for (int index = 0; index < count; index++) { - bodyList.add(doBuild(name + index, key + index)); + bodyList.add(doBuild(String.valueOf(index))); } return bodyList; } - private MgmtDistributionSetTypeRequestBodyPost doBuild(final String prefixName, final String prefixKey) { + private MgmtDistributionSetTypeRequestBodyPost doBuild(final String suffix) { final MgmtDistributionSetTypeRequestBodyPost body = new MgmtDistributionSetTypeRequestBodyPost(); - body.setKey(prefixKey); - body.setName(prefixName); + body.setKey(key + suffix); + body.setName(name + suffix); body.setDescription(description); body.setMandatorymodules(mandatorymodules); body.setOptionalmodules(optionalmodules); diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java index b2e544f88..1d633e440 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java @@ -96,7 +96,7 @@ public class SoftwareModuleBuilder { /** * Builds a list of multiple {@link MgmtSoftwareModuleRequestBodyPost} to * create multiple software module at once. An increasing number will be - * added to the name of the software module. The version and type will + * added to the version of the software module. The name and type will * remain the same. * * @param count @@ -106,16 +106,16 @@ public class SoftwareModuleBuilder { public List buildAsList(final int count) { final ArrayList bodyList = Lists.newArrayList(); for (int index = 0; index < count; index++) { - bodyList.add(doBuild(name + index)); + bodyList.add(doBuild(String.valueOf(index))); } return bodyList; } - private MgmtSoftwareModuleRequestBodyPost doBuild(final String prefixName) { + private MgmtSoftwareModuleRequestBodyPost doBuild(final String suffix) { final MgmtSoftwareModuleRequestBodyPost body = new MgmtSoftwareModuleRequestBodyPost(); - body.setName(prefixName); - body.setVersion(version); + body.setName(name); + body.setVersion(version + suffix); body.setType(type); body.setVendor(vendor); body.setDescription(description); diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java index 7981e61cf..7807d0f11 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java @@ -69,7 +69,7 @@ public class SoftwareModuleTypeBuilder { * {@link MgmtSoftwareModuleTypeRequestBodyPost} */ public List build() { - return Lists.newArrayList(doBuild(key, name)); + return Lists.newArrayList(doBuild("")); } /** @@ -85,15 +85,15 @@ public class SoftwareModuleTypeBuilder { public List buildAsList(final int count) { final ArrayList bodyList = Lists.newArrayList(); for (int index = 0; index < count; index++) { - bodyList.add(doBuild(key + index, name + index)); + bodyList.add(doBuild(String.valueOf(index))); } return bodyList; } - private MgmtSoftwareModuleTypeRequestBodyPost doBuild(final String prefixKey, final String prefixName) { + private MgmtSoftwareModuleTypeRequestBodyPost doBuild(final String suffix) { final MgmtSoftwareModuleTypeRequestBodyPost body = new MgmtSoftwareModuleTypeRequestBodyPost(); - body.setKey(prefixKey); - body.setName(prefixName); + body.setKey(key + suffix); + body.setName(name + suffix); body.setDescription(description); body.setMaxAssignments(maxAssignments); return body; diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java index 7bcc0af09..de81f5354 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.mgmt.client.resource.builder; -import java.util.ArrayList; import java.util.List; import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleTypeRequestBodyPost; @@ -65,32 +64,62 @@ public class TargetBuilder { * * @return a single entry list of {@link MgmtTargetRequestBody} */ - public List build() { - return Lists.newArrayList(doBuild(controllerId)); + public List buildAsList() { + return Lists.newArrayList(doBuild("")); + } + + /** + * Builds a single {@link MgmtTargetRequestBody}. + * + * @return build {@link MgmtTargetRequestBody} + */ + public MgmtTargetRequestBody build() { + return doBuild(""); } /** * Builds a list of multiple {@link MgmtTargetRequestBody} to create * multiple targets at once. An increasing number will be added to the - * controllerId of the target. The name and description will remain. + * controllerId and name of the target. The description will remain. * * @param count - * the amount of software module type bodies which should be - * created + * the amount of target bodies which should be created + * @param offset + * for * @return a list of {@link MgmtSoftwareModuleTypeRequestBodyPost} */ public List buildAsList(final int count) { - final ArrayList bodyList = Lists.newArrayList(); - for (int index = 0; index < count; index++) { - bodyList.add(doBuild(controllerId + index)); + + return buildAsList(0, count); + } + + /** + * Builds a list of multiple {@link MgmtTargetRequestBody} to create + * multiple targets at once. An increasing number will be added to the + * controllerId and name of the target starting from the provided offset. + * The description will remain. + * + * @param count + * the amount of target bodies which should be created + * @param offset + * for for index start + * @return a list of {@link MgmtSoftwareModuleTypeRequestBodyPost} + */ + public List buildAsList(final int offset, final int count) { + final List bodyList = Lists.newArrayList(); + for (int index = offset; index < count + offset; index++) { + bodyList.add(doBuild(String.valueOf(index))); } return bodyList; } - private MgmtTargetRequestBody doBuild(final String prefixControllerId) { + private MgmtTargetRequestBody doBuild(final String suffix) { final MgmtTargetRequestBody body = new MgmtTargetRequestBody(); - body.setControllerId(prefixControllerId); - body.setName(name); + body.setControllerId(controllerId + suffix); + if (name == null) { + name = controllerId; + } + body.setName(name + suffix); body.setDescription(description); return body; } diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java index 7e1f191a9..c6d9ca08c 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java @@ -9,8 +9,8 @@ package org.eclipse.hawkbit.mgmt.client; import org.eclipse.hawkbit.feign.core.client.FeignClientConfiguration; +import org.eclipse.hawkbit.mgmt.client.scenarios.ConfigurableScenario; import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample; -import org.eclipse.hawkbit.mgmt.client.scenarios.GettingStartedDefaultScenario; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -36,7 +36,7 @@ public class Application implements CommandLineRunner { private ClientConfigurationProperties configuration; @Autowired - private GettingStartedDefaultScenario gettingStarted; + private ConfigurableScenario configurableScenario; @Autowired private CreateStartedRolloutExample gettingStartedRolloutScenario; @@ -53,7 +53,7 @@ public class Application implements CommandLineRunner { } else { // run the getting started scenario which creates a setup of // distribution set and software modules to be used - gettingStarted.run(); + configurableScenario.run(); } } @@ -63,8 +63,8 @@ public class Application implements CommandLineRunner { } @Bean - public GettingStartedDefaultScenario gettingStartedDefaultScenario() { - return new GettingStartedDefaultScenario(); + public ConfigurableScenario configurableScenario() { + return new ConfigurableScenario(); } @Bean diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java index 68f35b550..255f813f9 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java @@ -8,6 +8,9 @@ */ package org.eclipse.hawkbit.mgmt.client; +import java.util.ArrayList; +import java.util.List; + import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -34,6 +37,79 @@ public class ClientConfigurationProperties { private String password = "admin"; // NOSONAR this password is only used for // examples + private final List scenarios = new ArrayList<>(); + + public static class Scenario { + private int targets = 100; + private int distributionSets = 10; + private int appModulesPerDistributionSet = 2; + private String dsName = "Package"; + private String smSwName = "Application"; + private String smFwName = "Firmware"; + private String targetName = "Device"; + + public String getTargetName() { + return targetName; + } + + public void setTargetName(final String targetName) { + this.targetName = targetName; + } + + public String getDsName() { + return dsName; + } + + public void setDsName(final String dsName) { + this.dsName = dsName; + } + + public String getSmSwName() { + return smSwName; + } + + public void setSmSwName(final String smSwName) { + this.smSwName = smSwName; + } + + public String getSmFwName() { + return smFwName; + } + + public void setSmFwName(final String smFwName) { + this.smFwName = smFwName; + } + + public int getTargets() { + return targets; + } + + public int getDistributionSets() { + return distributionSets; + } + + public int getAppModulesPerDistributionSet() { + return appModulesPerDistributionSet; + } + + public void setTargets(final int targets) { + this.targets = targets; + } + + public void setDistributionSets(final int distributionSets) { + this.distributionSets = distributionSets; + } + + public void setAppModulesPerDistributionSet(final int appModulesPerDistributionSet) { + this.appModulesPerDistributionSet = appModulesPerDistributionSet; + } + + } + + public List getScenarios() { + return scenarios; + } + public String getUrl() { return url; } diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java new file mode 100644 index 000000000..640c12a97 --- /dev/null +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client.scenarios; + +import java.util.List; + +import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties; +import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource; +import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder; +import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Default getting started scenario. + * + */ +public class ConfigurableScenario { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurableScenario.class); + + @Autowired + private MgmtDistributionSetClientResource distributionSetResource; + + @Autowired + private MgmtSoftwareModuleClientResource softwareModuleResource; + + @Autowired + private MgmtTargetClientResource targetResource; + + @Autowired + private ClientConfigurationProperties clientConfigurationProperties; + + /** + * Run the default getting started scenario. + */ + public void run() { + + LOGGER.info("Running Configurable Scenario..."); + + clientConfigurationProperties.getScenarios().parallelStream().forEach(this::createScenario); + } + + private void createScenario(final Scenario scenario) { + createTargets(scenario); + createDistributionSets(scenario); + } + + private void createDistributionSets(final Scenario scenario) { + distributionSetResource + .createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()).type("os_app") + .version("1.0.").buildAsList(scenario.getDistributionSets())) + .getBody().parallelStream().forEach(dsSet -> { + final List modules = softwareModuleResource + .createSoftwareModules(new SoftwareModuleBuilder().name(scenario.getSmFwName()) + .version(dsSet.getVersion()).type("os").build()) + .getBody(); + modules.addAll( + softwareModuleResource + .createSoftwareModules(new SoftwareModuleBuilder().name(scenario.getSmSwName()) + .version(dsSet.getVersion() + ".").type("application") + .buildAsList(scenario.getAppModulesPerDistributionSet())) + .getBody()); + + final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder(); + modules.forEach(module -> assign.id(module.getModuleId())); + + distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build()); + }); + } + + private void createTargets(final Scenario scenario) { + for (int i = 0; i < scenario.getTargets() / 100; i++) { + targetResource.createTargets(new TargetBuilder().controllerId(scenario.getTargetName()).buildAsList(i * 100, + (i + 1) * 100 > scenario.getTargets() ? scenario.getTargets() : (i + 1) * 100)); + } + } +} diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java index 90d61471e..913d2eaa4 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java @@ -36,7 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired; public class CreateStartedRolloutExample { /* known software module type name and key */ - private static final String SM_MODULE_TYPE = "firmware"; + private static final String SM_MODULE_TYPE = "gettingstarted-rollout-example"; /* known distribution set type name and key */ private static final String DS_MODULE_TYPE = SM_MODULE_TYPE; diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java deleted file mode 100644 index fdb824e8e..000000000 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.client.scenarios; - -import java.util.List; - -import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource; -import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetTypeClientResource; -import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; -import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleTypeClientResource; -import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder; -import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetTypeBuilder; -import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder; -import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder; -import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleTypeBuilder; -import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; -import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule; -import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * - * Default getting started scenario. - * - */ -public class GettingStartedDefaultScenario { - - private static final Logger LOGGER = LoggerFactory.getLogger(GettingStartedDefaultScenario.class); - - /* known software module type name and key */ - private static final String SM_MODULE_TYPE = "gettingstarted"; - - /* known distribution set type name and key */ - private static final String DS_MODULE_TYPE = SM_MODULE_TYPE; - - /* known distribution name of this getting started example */ - private static final String SM_EXAMPLE_NAME = "gettingstarted-example"; - - /* known distribution name of this getting started example */ - private static final String DS_EXAMPLE_NAME = SM_EXAMPLE_NAME; - - @Autowired - private MgmtDistributionSetClientResource distributionSetResource; - - @Autowired - private MgmtDistributionSetTypeClientResource distributionSetTypeResource; - - @Autowired - private MgmtSoftwareModuleClientResource softwareModuleResource; - - @Autowired - private MgmtSoftwareModuleTypeClientResource softwareModuleTypeResource; - - /** - * Run the default getting started scenario. - */ - public void run() { - - LOGGER.info("Running Getting-Started-Scenario..."); - - // create one SoftwareModuleTypes - LOGGER.info("Creating software module type {}", SM_MODULE_TYPE); - final List createdSoftwareModuleTypes = softwareModuleTypeResource - .createSoftwareModuleTypes(new SoftwareModuleTypeBuilder().key(SM_MODULE_TYPE).name(SM_MODULE_TYPE) - .maxAssignments(1).build()) - .getBody(); - - // create one DistributionSetType - LOGGER.info("Creating distribution set type {}", DS_MODULE_TYPE); - distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(DS_MODULE_TYPE) - .name(DS_MODULE_TYPE).mandatorymodules(createdSoftwareModuleTypes.get(0).getModuleId()).build()); - - // create three DistributionSet - final String dsVersion1 = "1.0.0"; - final String dsVersion2 = "2.0.0"; - final String dsVersion3 = "2.1.0"; - - LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion1); - final List distributionSetsRest1 = distributionSetResource.createDistributionSets( - new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion1).type(DS_MODULE_TYPE).build()) - .getBody(); - - LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion2); - final List distributionSetsRest2 = distributionSetResource.createDistributionSets( - new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion2).type(DS_MODULE_TYPE).build()) - .getBody(); - - LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion3); - final List distributionSetsRest3 = distributionSetResource.createDistributionSets( - new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion3).type(DS_MODULE_TYPE).build()) - .getBody(); - - // create three SoftwareModules - final String swVersion1 = "1"; - final String swVersion2 = "2"; - final String swVersion3 = "3"; - - LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion1); - final List softwareModulesRest1 = softwareModuleResource.createSoftwareModules( - new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion1).type(SM_MODULE_TYPE).build()) - .getBody(); - LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion2); - final List softwareModulesRest2 = softwareModuleResource.createSoftwareModules( - new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion2).type(SM_MODULE_TYPE).build()) - .getBody(); - LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion3); - final List softwareModulesRest3 = softwareModuleResource.createSoftwareModules( - new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion3).type(SM_MODULE_TYPE).build()) - .getBody(); - - // Assign SoftwareModules to DistributionSet - LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion1, - DS_EXAMPLE_NAME, dsVersion1); - distributionSetResource.assignSoftwareModules(distributionSetsRest1.get(0).getDsId(), - new SoftwareModuleAssigmentBuilder().id(softwareModulesRest1.get(0).getModuleId()).build()); - - LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion2, - DS_EXAMPLE_NAME, dsVersion2); - distributionSetResource.assignSoftwareModules(distributionSetsRest2.get(0).getDsId(), - new SoftwareModuleAssigmentBuilder().id(softwareModulesRest2.get(0).getModuleId()).build()); - - LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion3, - DS_EXAMPLE_NAME, dsVersion3); - distributionSetResource.assignSoftwareModules(distributionSetsRest3.get(0).getDsId(), - new SoftwareModuleAssigmentBuilder().id(softwareModulesRest3.get(0).getModuleId()).build()); - } -} diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties index d3a3eb969..d989dcf3d 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties @@ -11,4 +11,13 @@ hawkbit.url=localhost:8080 hawkbit.username=admin hawkbit.password=admin -spring.main.show-banner=false \ No newline at end of file +spring.main.show-banner=false + +#hawkbit.scenarios.[0].targets=0 +#hawkbit.scenarios.[0].ds-name=gettingstarted-example +#hawkbit.scenarios.[0].distribution-sets=3 +#hawkbit.scenarios.[0].sm-fw-name=gettingstarted-example +#hawkbit.scenarios.[0].sm-sw-name=gettingstarted-example + +hawkbit.scenarios.[0].targets=10000 +hawkbit.scenarios.[0].distribution-sets=100 \ No newline at end of file From 72940d854aeefff501f8fb2f0cab45fa5578d527 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Fri, 10 Jun 2016 09:40:05 +0200 Subject: [PATCH 07/82] Optimize layout Configure new Rollout Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 1 + .../hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../rollout/AddUpdateRolloutWindowLayout.java | 56 ++++++++++++------- .../hawkbit/customstyles/popup-common.scss | 4 ++ 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 309c111ea..85b55d69d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -208,6 +208,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se addStyleName("lay-color"); final FormLayout formLayout = new FormLayout(); + formLayout.setCaption(null); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); formLayout.addComponent(versionTextField); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 7b5df4a8f..754f61ed2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -197,7 +197,7 @@ public class CommonDialogWindow extends Window implements Serializable { setCaption(caption); setContent(mainLayout); - setResizable(true); + setResizable(false); center(); setModal(true); addStyleName("fontsize"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 1226ec5fb..2e419724b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.RolloutManagement; @@ -61,6 +62,7 @@ import com.vaadin.data.Validator; import com.vaadin.data.validator.IntegerRangeValidator; import com.vaadin.data.validator.RegexpValidator; import com.vaadin.event.FieldEvents.TextChangeEvent; +import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.ComboBox; @@ -224,21 +226,22 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { setSizeUndefined(); setRows(9); setColumns(3); + setStyleName("marginTop"); - addComponent(getLabel("textfield.name"), 0, 0); + addComponent(getMandatoryLabel("textfield.name"), 0, 0); addComponent(rolloutName, 1, 0); - addComponent(getLabel("prompt.distribution.set"), 0, 1); + addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1); addComponent(distributionSet, 1, 1); - addComponent(getLabel("prompt.target.filter"), 0, 2); + addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2); addComponent(targetFilterQueryCombo, 1, 2); addComponent(totalTargetsLabel, 2, 2); - addComponent(getLabel("prompt.number.of.groups"), 0, 3); + addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3); addComponent(noOfGroups, 1, 3); addComponent(groupSizeLabel, 2, 3); - addComponent(getLabel("prompt.tigger.threshold"), 0, 4); + addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4); addComponent(triggerThreshold, 1, 4); addComponent(getPercentHintLabel(), 2, 4); - addComponent(getLabel("prompt.error.threshold"), 0, 5); + addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5); addComponent(errorThreshold, 1, 5); addComponent(errorThresholdOptionGroup, 2, 5); addComponent(getLabel("textfield.description"), 0, 6); @@ -248,12 +251,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { rolloutName.focus(); } + private Label getMandatoryLabel(final String key) { + final Label mandatoryLabel = getLabel(i18n.get(key)); + mandatoryLabel.setContentMode(ContentMode.HTML); + mandatoryLabel.setValue(mandatoryLabel.getValue().concat(" *")); + return mandatoryLabel; + } + private Label getLabel(final String key) { return SPUIComponentProvider.getLabel(i18n.get(key), SPUILabelDefinitions.SP_LABEL_SIMPLE); } private TextField getTextfield(final String key) { - return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get(key), true, + return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get(key), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); } @@ -340,7 +350,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private ComboBox createTargetFilterQueryCombo() { final ComboBox targetFilter = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, - true, "", i18n.get("prompt.target.filter")); + false, "", i18n.get("prompt.target.filter")); targetFilter.setImmediate(true); targetFilter.setPageLength(7); targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); @@ -625,8 +635,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private ComboBox createDistributionSetCombo() { - final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, true, "", - i18n.get("prompt.distribution.set")); + final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, false, + "", i18n.get("prompt.distribution.set")); dsSet.setImmediate(true); dsSet.setPageLength(7); dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); @@ -685,10 +695,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); - final int groupSize = getGroupSize(); - new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, groupSize) - .validate(Integer.valueOf(value.toString())); + if (StringUtils.isNotBlank(value.toString())) { + new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + final int groupSize = getGroupSize(); + new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, + groupSize).validate(Integer.valueOf(value.toString())); + } } } // suppress the need of preserve original exception, will blow @@ -710,9 +722,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); - new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100) - .validate(Integer.valueOf(value.toString())); + if (StringUtils.isNotBlank(value.toString())) { + new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100) + .validate(Integer.valueOf(value.toString())); + } } // suppress the need of preserve original exception, will blow // up the @@ -729,9 +743,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); - new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500) - .validate(Integer.valueOf(value.toString())); + if (StringUtils.isNotBlank(value.toString())) { + new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500) + .validate(Integer.valueOf(value.toString())); + } } // suppress the need of preserve original exception, will blow // up the diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss index 457fc266d..602298766 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss @@ -53,4 +53,8 @@ font-size: 16px; } + .v-gridlayout .v-gridlayout-marginTop { + padding-top: 20px !important; + } + } From 3e5f1f75a07e2b7d148cff211a3990be3e896601 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Fri, 10 Jun 2016 15:47:40 +0200 Subject: [PATCH 08/82] Improve code select all table entries Signed-off-by: Melanie Retter --- .../artifacts/event/SoftwareModuleEvent.java | 6 +- .../event/SoftwareModuleTypeEvent.java | 8 +-- .../smtable/SoftwareModuleTableLayout.java | 3 +- .../filterlayout/AbstractFilterButtons.java | 24 ++++---- .../table/AbstractNamedVersionTable.java | 7 --- .../dstable/DistributionSetTableLayout.java | 7 +-- .../event/DistributionSetTableEvent.java | 60 ------------------- .../event/DistributionSetTypeEvent.java | 8 +-- 8 files changed, 19 insertions(+), 104 deletions(-) delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java index 1764f8998..c01257154 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java @@ -23,15 +23,11 @@ public class SoftwareModuleEvent extends BaseEntityEvent { * */ public enum SoftwareModuleEventType { - ARTIFACTS_CHANGED, ASSIGN_SOFTWARE_MODULE + ARTIFACTS_CHANGED, ASSIGN_SOFTWARE_MODULE, SELECT_ALL } private SoftwareModuleEventType softwareModuleEventType; - public SoftwareModuleEvent() { - super(null, null); - } - /** * Creates software module event. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java index f1b8deb72..7262aee72 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleTypeEvent.java @@ -12,20 +12,14 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType; /** * Event to represent software module type add, update or delete. - * - * - * */ public class SoftwareModuleTypeEvent { /** * Software module type events in the Upload UI. - * - * - * */ public enum SoftwareModuleTypeEnum { - ADD_SOFTWARE_MODULE_TYPE, DELETE_SOFTWARE_MODULE_TYPE, UPDATE_SOFTWARE_MODULE_TYPE, SELECT_ALL + ADD_SOFTWARE_MODULE_TYPE, DELETE_SOFTWARE_MODULE_TYPE, UPDATE_SOFTWARE_MODULE_TYPE } private SoftwareModuleType softwareModuleType; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java index 096550d7c..ec6b41e23 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; import org.springframework.beans.factory.annotation.Autowired; @@ -72,7 +73,7 @@ public class SoftwareModuleTableLayout extends AbstractTableLayout { public void handleAction(final Action action, final Object sender, final Object target) { if (ACTION_CTRL_A.equals(action)) { smTable.selectAll(); - getEventBus().publish(this, new SoftwareModuleEvent()); + getEventBus().publish(this, new SoftwareModuleEvent(SoftwareModuleEventType.SELECT_ALL, null)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java index b637c88f6..2b0eee279 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java @@ -16,7 +16,6 @@ import javax.annotation.PreDestroy; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUITagButtonStyle; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -49,9 +48,6 @@ public abstract class AbstractFilterButtons extends Table { private AbstractFilterButtonClickBehaviour filterButtonClickBehaviour; - @Autowired - protected I18N i18n; - /** * Initialize layout of filter buttons. * @@ -198,16 +194,16 @@ public abstract class AbstractFilterButtons extends Table { setContainerDataSource(createButtonsLazyQueryContainer()); } - /** - * Select all rows in the table. - */ - public void selectAll() { - setValue(createButtonsLazyQueryContainer().getItemIds()); - } - - public void unSelectAll() { - setValue(null); - } + // /** + // * Select all rows in the table. + // */ + // public void selectAll() { + // setValue(createButtonsLazyQueryContainer().getItemIds()); + // } + // + // public void unSelectAll() { + // setValue(null); + // } /** * Id of the buttons table to be used in test cases. diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java index f99e01fe7..3122841ae 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java @@ -62,11 +62,4 @@ public abstract class AbstractNamedVersionTable { - - /** - * DistributionSet table components events. - * - */ - public enum DistributionSetComponentEvent { - SELECT_ALL - } - - private DistributionSetComponentEvent distributionSetComponentEvent; - - /** - * Constructor. - * - * @param eventType - * the event type. - * @param entity - * the entity - */ - public DistributionSetTableEvent(final BaseEntityEventType eventType, final DistributionSet entity) { - super(eventType, entity); - } - - /** - * The component event. - * - * @param DistributionSetTableEvent - * the distributionSet component event. - */ - public DistributionSetTableEvent(final DistributionSetComponentEvent distributionSetComponentEvent) { - super(null, null); - this.distributionSetComponentEvent = distributionSetComponentEvent; - } - - public DistributionSetComponentEvent getDistributionSetComponentEvent() { - return distributionSetComponentEvent; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java index 798d2a43d..3df0a7dd3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java @@ -11,19 +11,15 @@ package org.eclipse.hawkbit.ui.distributions.event; import org.eclipse.hawkbit.repository.model.DistributionSetType; /** - * - * + * DistributionSetTypeEvent */ public class DistributionSetTypeEvent { /** * DistributionSet type events in the Distribution UI. - * - * - * */ public enum DistributionSetTypeEnum { - ADD_DIST_SET_TYPE, DELETE_DIST_SET_TYPE, UPDATE_DIST_SET_TYPE, ON_VALUE_CHANGE + ADD_DIST_SET_TYPE, DELETE_DIST_SET_TYPE, UPDATE_DIST_SET_TYPE, ON_VALUE_CHANGE, SELECT_ALL } private DistributionSetType distributionSetType; From a9c5dcef6975bcc581117cce350b34473b06b52b Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 13 Jun 2016 09:03:01 +0200 Subject: [PATCH 09/82] Added integration option with device simulator. Signed-off-by: Kai Zimmermann --- .../resource/builder/TargetBuilder.java | 12 ++ .../hawkbit/mgmt/client/Application.java | 27 +++ .../client/ClientConfigurationProperties.java | 41 +++++ .../scenarios/ConfigurableScenario.java | 78 +++++++-- .../CreateStartedRolloutExample.java | 2 + .../client/scenarios/upload/ArtifactFile.java | 103 +++++++++++ .../upload/FeignMultipartEncoder.java | 160 ++++++++++++++++++ .../src/main/resources/application.properties | 5 +- .../model/target/MgmtTargetRequestBody.java | 11 ++ .../mgmt/rest/resource/MgmtTargetMapper.java | 1 + .../rest/resource/MgmtTargetResourceTest.java | 8 +- .../hawkbit/repository/TargetManagement.java | 19 --- .../hawkbit/repository/model/TargetInfo.java | 11 +- .../repository/jpa/JpaTargetManagement.java | 19 +-- .../repository/jpa/model/JpaTargetInfo.java | 2 +- .../hawkbit/rest/util/JsonBuilder.java | 36 ++-- 16 files changed, 459 insertions(+), 76 deletions(-) create mode 100644 examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java create mode 100644 examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java index de81f5354..023557829 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java @@ -27,6 +27,7 @@ public class TargetBuilder { private String controllerId; private String name; private String description; + private String address; /** * @param controllerId @@ -48,6 +49,16 @@ public class TargetBuilder { return this; } + /** + * @param address + * the address of the target + * @return the builder itself + */ + public TargetBuilder address(final String address) { + this.address = address; + return this; + } + /** * @param description * the description of the target @@ -121,6 +132,7 @@ public class TargetBuilder { } body.setName(name + suffix); body.setDescription(description); + body.setAddress(address); return body; } diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java index c6d9ca08c..036c19ed1 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java @@ -9,8 +9,12 @@ package org.eclipse.hawkbit.mgmt.client; import org.eclipse.hawkbit.feign.core.client.FeignClientConfiguration; +import org.eclipse.hawkbit.feign.core.client.IgnoreMultipleConsumersProducersSpringMvcContract; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; import org.eclipse.hawkbit.mgmt.client.scenarios.ConfigurableScenario; import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample; +import org.eclipse.hawkbit.mgmt.client.scenarios.upload.FeignMultipartEncoder; +import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -18,11 +22,19 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.netflix.feign.EnableFeignClients; +import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.hateoas.hal.Jackson2HalModule; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +import feign.Feign; +import feign.Logger; import feign.auth.BasicAuthRequestInterceptor; +import feign.jackson.JacksonDecoder; @SpringBootApplication @EnableFeignClients @@ -72,6 +84,21 @@ public class Application implements CommandLineRunner { return new CreateStartedRolloutExample(); } + @Bean + public MgmtSoftwareModuleClientResource uploadSoftwareModule() { + final ObjectMapper mapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .registerModule(new Jackson2HalModule()); + + return Feign.builder().contract(new IgnoreMultipleConsumersProducersSpringMvcContract()) + .requestInterceptor( + new BasicAuthRequestInterceptor(configuration.getUsername(), configuration.getPassword())) + .logger(new Logger.ErrorLogger()).encoder(new FeignMultipartEncoder()) + .decoder(new ResponseEntityDecoder(new JacksonDecoder(mapper))) + .target(MgmtSoftwareModuleClientResource.class, + configuration.getUrl() + MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING); + } + private boolean containsArg(final String containsArg, final String... args) { for (final String arg : args) { if (arg.equalsIgnoreCase(containsArg)) { diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java index 255f813f9..cc5fe27e9 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java @@ -40,6 +40,7 @@ public class ClientConfigurationProperties { private final List scenarios = new ArrayList<>(); public static class Scenario { + private String tenant = "DEFAULT"; private int targets = 100; private int distributionSets = 10; private int appModulesPerDistributionSet = 2; @@ -47,6 +48,46 @@ public class ClientConfigurationProperties { private String smSwName = "Application"; private String smFwName = "Firmware"; private String targetName = "Device"; + private int artifactsPerSM = 1; + private String targetAddress = "amqp:/simulator.replyTo"; + + /** + * Artifact size. Values can use the suffixed "MB" or "KB" to indicate a + * Megabyte or Kilobyte size. + */ + private String artifactSize = "1MB"; + + public String getTargetAddress() { + return targetAddress; + } + + public void setTargetAddress(final String targetAddress) { + this.targetAddress = targetAddress; + } + + public String getTenant() { + return tenant; + } + + public void setTenant(final String tenant) { + this.tenant = tenant; + } + + public int getArtifactsPerSM() { + return artifactsPerSM; + } + + public void setArtifactsPerSM(final int artifactsPerSM) { + this.artifactsPerSM = artifactsPerSM; + } + + public String getArtifactSize() { + return artifactSize; + } + + public void setArtifactSize(final String artifactSize) { + this.artifactSize = artifactSize; + } public String getTargetName() { return targetName; diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java index 640c12a97..60144a88e 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java @@ -9,20 +9,25 @@ package org.eclipse.hawkbit.mgmt.client.scenarios; import java.util.List; +import java.util.Random; import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties; import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario; import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource; import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtSystemManagementClientResource; import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource; import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder; import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder; import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder; import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder; +import org.eclipse.hawkbit.mgmt.client.scenarios.upload.ArtifactFile; +import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; /** * @@ -37,11 +42,19 @@ public class ConfigurableScenario { private MgmtDistributionSetClientResource distributionSetResource; @Autowired + @Qualifier("mgmtSoftwareModuleClientResource") private MgmtSoftwareModuleClientResource softwareModuleResource; + @Autowired + @Qualifier("uploadSoftwareModule") + private MgmtSoftwareModuleClientResource uploadSoftwareModule; + @Autowired private MgmtTargetClientResource targetResource; + @Autowired + private MgmtSystemManagementClientResource systemManagementResource; + @Autowired private ClientConfigurationProperties clientConfigurationProperties; @@ -56,37 +69,76 @@ public class ConfigurableScenario { } private void createScenario(final Scenario scenario) { + systemManagementResource.deleteTenant(scenario.getTenant()); createTargets(scenario); createDistributionSets(scenario); } private void createDistributionSets(final Scenario scenario) { + final byte[] artifact = generateArtifact(scenario); + distributionSetResource .createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()).type("os_app") .version("1.0.").buildAsList(scenario.getDistributionSets())) .getBody().parallelStream().forEach(dsSet -> { - final List modules = softwareModuleResource - .createSoftwareModules(new SoftwareModuleBuilder().name(scenario.getSmFwName()) - .version(dsSet.getVersion()).type("os").build()) - .getBody(); - modules.addAll( - softwareModuleResource - .createSoftwareModules(new SoftwareModuleBuilder().name(scenario.getSmSwName()) - .version(dsSet.getVersion() + ".").type("application") - .buildAsList(scenario.getAppModulesPerDistributionSet())) - .getBody()); + final List modules = addModules(scenario, dsSet, artifact); final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder(); modules.forEach(module -> assign.id(module.getModuleId())); - distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build()); }); } + private List addModules(final Scenario scenario, final MgmtDistributionSet dsSet, + final byte[] artifact) { + final List modules = softwareModuleResource.createSoftwareModules( + new SoftwareModuleBuilder().name(scenario.getSmFwName()).version(dsSet.getVersion()).type("os").build()) + .getBody(); + modules.addAll(softwareModuleResource + .createSoftwareModules( + new SoftwareModuleBuilder().name(scenario.getSmSwName()).version(dsSet.getVersion() + ".") + .type("application").buildAsList(scenario.getAppModulesPerDistributionSet())) + .getBody()); + + for (int x = 0; x < scenario.getArtifactsPerSM(); x++) { + modules.forEach(module -> { + final ArtifactFile file = new ArtifactFile("dummyfile.dummy", null, "multipart/form-data", artifact); + uploadSoftwareModule.uploadArtifact(module.getModuleId(), file, null, null, null); + }); + } + + return modules; + } + + private byte[] generateArtifact(final Scenario scenario) { + // create random object + final Random random = new Random(); + + // create byte array + final byte[] nbyte = new byte[parseSize(scenario.getArtifactSize())]; + + // put the next byte in the array + random.nextBytes(nbyte); + + return nbyte; + } + private void createTargets(final Scenario scenario) { for (int i = 0; i < scenario.getTargets() / 100; i++) { - targetResource.createTargets(new TargetBuilder().controllerId(scenario.getTargetName()).buildAsList(i * 100, - (i + 1) * 100 > scenario.getTargets() ? scenario.getTargets() : (i + 1) * 100)); + targetResource.createTargets(new TargetBuilder().controllerId(scenario.getTargetName()) + .address(scenario.getTargetAddress()).buildAsList(i * 100, + (i + 1) * 100 > scenario.getTargets() ? scenario.getTargets() - i * 100 : 100)); } } + + private int parseSize(final String s) { + final String size = s.toUpperCase(); + if (size.endsWith("KB")) { + return Integer.valueOf(size.substring(0, size.length() - 2)) * 1024; + } + if (size.endsWith("MB")) { + return Integer.valueOf(size.substring(0, size.length() - 2)) * 1024 * 1024; + } + return Integer.valueOf(size); + } } diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java index 913d2eaa4..b450bbde2 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody; import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule; import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; /** * Example for creating and starting a Rollout. @@ -45,6 +46,7 @@ public class CreateStartedRolloutExample { private MgmtDistributionSetClientResource distributionSetResource; @Autowired + @Qualifier("mgmtSoftwareModuleClientResource") private MgmtSoftwareModuleClientResource softwareModuleResource; @Autowired diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java new file mode 100644 index 000000000..adad1fe77 --- /dev/null +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client.scenarios.upload; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.springframework.util.Assert; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; + +public class ArtifactFile implements MultipartFile { + + private final String name; + + private final String originalFilename; + + private final String contentType; + + private final byte[] content; + + /** + * Create a new ArtifactFile with the given content. + * + * @param name + * the name of the file + * @param content + * the content of the file + */ + public ArtifactFile(final String name, final byte[] content) { + this(name, "", null, content); + } + + /** + * Create a new ArtifactFile with the given content. + * + * @param name + * of the file + * @param originalFilename + * the original filename (as on the client's machine) + * @param contentType + * the content type + * @param content + * of the file + */ + public ArtifactFile(final String name, final String originalFilename, final String contentType, + final byte[] content) { + Assert.hasLength(name, "Name must not be null"); + this.name = name; + this.originalFilename = originalFilename != null ? originalFilename : ""; + this.contentType = contentType; + this.content = content != null ? content : new byte[0]; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getOriginalFilename() { + return this.originalFilename; + } + + @Override + public String getContentType() { + return this.contentType; + } + + @Override + public boolean isEmpty() { + return this.content.length == 0; + } + + @Override + public long getSize() { + return this.content.length; + } + + @Override + public byte[] getBytes() throws IOException { + return this.content; + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(this.content); + } + + @Override + public void transferTo(final File dest) throws IOException { + FileCopyUtils.copy(this.content, dest); + } + +} diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java new file mode 100644 index 000000000..fdf5462da --- /dev/null +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.scenarios.upload; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Type; +import java.nio.charset.Charset; +import java.util.List; +import java.util.Map.Entry; + +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.multipart.MultipartFile; + +import feign.RequestTemplate; +import feign.codec.EncodeException; +import feign.codec.Encoder; + +/** + * A feign encoder implementation which handles {@link MultipartFile} body. + */ +public class FeignMultipartEncoder implements Encoder { + + private final List> converters = new RestTemplate().getMessageConverters(); + private final HttpHeaders multipartHeaders = new HttpHeaders(); + private final HttpHeaders jsonHeaders = new HttpHeaders(); + + public static final Charset UTF_8 = Charset.forName("UTF-8"); + + public FeignMultipartEncoder() { + multipartHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); + jsonHeaders.setContentType(MediaType.APPLICATION_JSON); + } + + @Override + public void encode(final Object object, final Type bodyType, final RequestTemplate template) + throws EncodeException { + + encodeMultipartFormRequest(object, template); + + } + + private void encodeMultipartFormRequest(final Object value, final RequestTemplate template) { + if (value == null) { + throw new EncodeException("Cannot encode request with null value."); + } + if (!isMultipartFile(value)) { + throw new EncodeException("Only multipart can be handled by this encoder"); + } + encodeRequest(encodeMultipartFile((MultipartFile) value), multipartHeaders, template); + } + + @SuppressWarnings("unchecked") + private void encodeRequest(final Object value, final HttpHeaders requestHeaders, final RequestTemplate template) + throws EncodeException { + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + final HttpOutputMessage dummyRequest = new HttpOutputMessageImpl(outputStream, requestHeaders); + try { + final Class requestType = value.getClass(); + final MediaType requestContentType = requestHeaders.getContentType(); + for (final HttpMessageConverter messageConverter : converters) { + if (messageConverter.canWrite(requestType, requestContentType)) { + ((HttpMessageConverter) messageConverter).write(value, requestContentType, dummyRequest); + break; + } + } + } catch (final IOException ex) { + throw new EncodeException("Cannot encode request.", ex); + } + final HttpHeaders headers = dummyRequest.getHeaders(); + if (headers != null) { + for (final Entry> entry : headers.entrySet()) { + template.header(entry.getKey(), entry.getValue()); + } + } + /* + * we should use a template output stream... this will cause issues if + * files are too big, since the whole request will be in memory. + */ + template.body(outputStream.toByteArray(), UTF_8); + } + + private MultiValueMap encodeMultipartFile(final MultipartFile file) { + try { + final MultiValueMap multiValueMap = new LinkedMultiValueMap<>(); + multiValueMap.add("file", new MultipartFileResource(file.getName(), file.getSize(), file.getInputStream())); + return multiValueMap; + } catch (final IOException ex) { + throw new EncodeException("Cannot encode request.", ex); + } + } + + private boolean isMultipartFile(final Object object) { + return object instanceof MultipartFile; + } + + private class HttpOutputMessageImpl implements HttpOutputMessage { + + private final OutputStream body; + private final HttpHeaders headers; + + public HttpOutputMessageImpl(final OutputStream body, final HttpHeaders headers) { + this.body = body; + this.headers = headers; + } + + @Override + public OutputStream getBody() throws IOException { + return body; + } + + @Override + public HttpHeaders getHeaders() { + return headers; + } + + } + + /** + * Dummy resource class. Wraps file content and its original name. + */ + static class MultipartFileResource extends InputStreamResource { + + private final String filename; + private final long size; + + public MultipartFileResource(final String filename, final long size, final InputStream inputStream) { + super(inputStream); + this.size = size; + this.filename = filename; + } + + @Override + public String getFilename() { + return this.filename; + } + + @Override + public InputStream getInputStream() throws IOException, IllegalStateException { + return super.getInputStream(); // To change body of generated + // methods, choose Tools | Templates. + } + + @Override + public long contentLength() throws IOException { + return size; + } + + } +} diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties index d989dcf3d..f538bb1cb 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties @@ -7,7 +7,7 @@ # http://www.eclipse.org/legal/epl-v10.html # -hawkbit.url=localhost:8080 +hawkbit.url=http://localhost:8080 hawkbit.username=admin hawkbit.password=admin @@ -20,4 +20,5 @@ spring.main.show-banner=false #hawkbit.scenarios.[0].sm-sw-name=gettingstarted-example hawkbit.scenarios.[0].targets=10000 -hawkbit.scenarios.[0].distribution-sets=100 \ No newline at end of file +hawkbit.scenarios.[0].distribution-sets=100 +hawkbit.scenarios.[0].artifactsPerSM=0 \ No newline at end of file diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java index bc40326e4..b9c0b001a 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java @@ -18,6 +18,9 @@ public class MgmtTargetRequestBody { @JsonProperty(required = true) private String controllerId; + @JsonProperty + private String address; + /** * @return the name */ @@ -66,4 +69,12 @@ public class MgmtTargetRequestBody { return this; } + public String getAddress() { + return address; + } + + public void setAddress(final String address) { + this.address = address; + } + } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index f00998d29..d77cbaa53 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -182,6 +182,7 @@ public final class MgmtTargetMapper { final Target target = entityFactory.generateTarget(targetRest.getControllerId()); target.setDescription(targetRest.getDescription()); target.setName(targetRest.getName()); + target.getTargetInfo().setAddress(targetRest.getAddress()); return target; } diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index 1375307d4..ed6ee4a93 100644 --- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -40,11 +40,11 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.Status; -import org.eclipse.hawkbit.repository.test.util.WithUser; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.test.util.WithUser; import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest; import org.eclipse.hawkbit.rest.exception.MessageNotReadableException; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; @@ -109,8 +109,8 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { final String knownTargetId = "targetId"; final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); actions.get(0).setStatus(Status.FINISHED); - controllerManagament.addUpdateActionStatus(entityFactory.generateActionStatus(actions.get(0), - Status.FINISHED, System.currentTimeMillis(), "testmessage")); + controllerManagament.addUpdateActionStatus(entityFactory.generateActionStatus(actions.get(0), Status.FINISHED, + System.currentTimeMillis(), "testmessage")); final PageRequest pageRequest = new PageRequest(0, 1000, Direction.ASC, ActionFields.ID.getFieldName()); final ActionStatus status = deploymentManagement @@ -682,6 +682,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { final Target test1 = entityFactory.generateTarget("id1"); test1.setDescription("testid1"); test1.setName("testname1"); + test1.getTargetInfo().setAddress("amqp://test123/foobar"); final Target test2 = entityFactory.generateTarget("id2"); test2.setDescription("testid2"); test2.setName("testname2"); @@ -704,6 +705,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { .andExpect(jsonPath("[0].description", equalTo("testid1"))) .andExpect(jsonPath("[0].createdAt", not(equalTo(0)))) .andExpect(jsonPath("[0].createdBy", equalTo("bumlux"))) + .andExpect(jsonPath("[0].address", equalTo("amqp://test123/foobar"))) .andExpect(jsonPath("[1].name", equalTo("testname2"))) .andExpect(jsonPath("[1].createdBy", equalTo("bumlux"))) .andExpect(jsonPath("[1].controllerId", equalTo("id2"))) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index 9054127ef..5fdfb318e 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -179,25 +179,6 @@ public interface TargetManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) List createTargets(@NotNull Collection targets); - /** - * creating a new {@link Target} including poll status data. useful - * especially in plug and play scenarios. - * - * @param targets - * to be created * - * @param status - * of the target - * @param lastTargetQuery - * if a plug and play case - * @param address - * if a plug and play case - * - * @return newly created target - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET) - List createTargets(@NotNull Collection targets, @NotNull TargetUpdateStatus status, - Long lastTargetQuery, URI address); - /** * Deletes all targets with the given IDs. * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index 6317f9783..2eb2f05c7 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -16,10 +16,19 @@ import java.util.concurrent.TimeUnit; public interface TargetInfo extends Serializable { /** - * @return the address under whioch the target can be reached + * @return the address under which the target can be reached */ URI getAddress(); + /** + * @param address + * the target address to set + * + * @throws IllegalArgumentException + * If the given string violates RFC 2396 + */ + void setAddress(String address); + /** * @return {@link Target} this info element belongs to. */ diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 892ddc771..f318962bf 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -608,24 +608,7 @@ public class JpaTargetManagement implements TargetManagement { } final List savedTargets = new ArrayList<>(); for (final Target t : targets) { - final Target myTarget = createTarget(t); - savedTargets.add(myTarget); - } - return savedTargets; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createTargets(final Collection targets, final TargetUpdateStatus status, - final Long lastTargetQuery, final URI address) { - if (targetRepository.countByControllerIdIn( - targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) { - throw new EntityAlreadyExistsException(); - } - final List savedTargets = new ArrayList<>(); - for (final Target t : targets) { - final Target myTarget = createTarget(t, status, lastTargetQuery, address); + final Target myTarget = createTarget(t, TargetUpdateStatus.UNKNOWN, null, t.getTargetInfo().getAddress()); savedTargets.add(myTarget); } return savedTargets; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index 6b5a3d1af..15abc2d61 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -168,7 +168,7 @@ public class JpaTargetInfo implements Persistable, TargetInfo { /** * @param address - * the ipAddress to set + * the target address to set * * @throws IllegalArgumentException * If the given string violates RFC 2396 diff --git a/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/util/JsonBuilder.java b/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/util/JsonBuilder.java index f67f15815..51cbd7a99 100644 --- a/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/util/JsonBuilder.java +++ b/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/util/JsonBuilder.java @@ -41,9 +41,9 @@ public abstract class JsonBuilder { try { builder.append(new JSONObject().put("name", module.getName()) .put("description", module.getDescription()).put("type", module.getType().getKey()) - .put("id", Long.MAX_VALUE).put("vendor", module.getVendor()) - .put("version", module.getVersion()).put("createdAt", "0").put("updatedAt", "0") - .put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh").toString()); + .put("id", Long.MAX_VALUE).put("vendor", module.getVendor()).put("version", module.getVersion()) + .put("createdAt", "0").put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh") + .put("updatedBy", "fghdfkjghdfkjh").toString()); } catch (final Exception e) { e.printStackTrace(); } @@ -185,15 +185,13 @@ public abstract class JsonBuilder { final List messages = new ArrayList(); messages.add(message); - return new JSONObject() - .put("id", id) - .put("time", "20140511T121314") + return new JSONObject().put("id", id).put("time", "20140511T121314") .put("status", - new JSONObject() - .put("execution", execution) + new JSONObject().put("execution", execution) .put("result", new JSONObject().put("finished", finished).put("progress", - new JSONObject().put("cnt", 2).put("of", 5))).put("details", messages)) + new JSONObject().put("cnt", 2).put("of", 5))) + .put("details", messages)) .toString(); } @@ -380,10 +378,13 @@ public abstract class JsonBuilder { int i = 0; for (final Target target : targets) { try { + final String address = target.getTargetInfo().getAddress() != null + ? target.getTargetInfo().getAddress().toString() : null; + builder.append(new JSONObject().put("controllerId", target.getControllerId()) - .put("description", target.getDescription()).put("name", target.getName()) - .put("createdAt", "0").put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh") - .put("updatedBy", "fghdfkjghdfkjh").toString()); + .put("description", target.getDescription()).put("name", target.getName()).put("createdAt", "0") + .put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh") + .put("address", address).toString()); } catch (final Exception e) { e.printStackTrace(); } @@ -441,9 +442,7 @@ public abstract class JsonBuilder { throws JSONException { final List messages = new ArrayList(); messages.add(message); - return new JSONObject() - .put("id", id) - .put("time", "20140511T121314") + return new JSONObject().put("id", id).put("time", "20140511T121314") .put("status", new JSONObject().put("execution", execution) .put("result", new JSONObject().put("finished", "success")).put("details", messages)) @@ -453,13 +452,12 @@ public abstract class JsonBuilder { public static String configData(final String id, final Map attributes, final String execution) throws JSONException { - return new JSONObject() - .put("id", id) - .put("time", "20140511T121314") + return new JSONObject().put("id", id).put("time", "20140511T121314") .put("status", new JSONObject().put("execution", execution) .put("result", new JSONObject().put("finished", "success")) - .put("details", new ArrayList())).put("data", attributes).toString(); + .put("details", new ArrayList())) + .put("data", attributes).toString(); } From 1b5975523947795ecd5e38e2d20992e90448b23e Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 13 Jun 2016 17:49:09 +0200 Subject: [PATCH 10/82] Optimize multiselect Signed-off-by: Melanie Retter --- .../filterlayout/AbstractFilterButtons.java | 12 --------- .../dstable/DistributionSetTableLayout.java | 7 +++--- .../event/DistributionSetTableEvent.java | 25 +++++++++++++++++++ .../event/DistributionSetTypeEvent.java | 2 +- .../event/SoftwareModuleTableEvent.java | 25 +++---------------- .../dstable/DistributionTableLayout.java | 7 +++--- .../event/DistributionTableEvent.java | 23 ++--------------- .../ui/management/event/TargetTableEvent.java | 4 +-- 8 files changed, 41 insertions(+), 64 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java index 2b0eee279..aec0029d0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterButtons.java @@ -77,7 +77,6 @@ public abstract class AbstractFilterButtons extends Table { setDragMode(TableDragMode.NONE); setSelectable(false); setSizeFull(); - setMultiSelect(true); } private void setStyle() { @@ -194,17 +193,6 @@ public abstract class AbstractFilterButtons extends Table { setContainerDataSource(createButtonsLazyQueryContainer()); } - // /** - // * Select all rows in the table. - // */ - // public void selectAll() { - // setValue(createButtonsLazyQueryContainer().getItemIds()); - // } - // - // public void unSelectAll() { - // setValue(null); - // } - /** * Id of the buttons table to be used in test cases. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java index ef6d3ae4a..cf365b081 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java @@ -11,8 +11,8 @@ package org.eclipse.hawkbit.ui.distributions.dstable; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent.DistributionTableComponentEvent; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.event.Action; @@ -77,7 +77,8 @@ public class DistributionSetTableLayout extends AbstractTableLayout { public void handleAction(final Action action, final Object sender, final Object target) { if (ACTION_CTRL_A.equals(action)) { dsTable.selectAll(); - getEventBus().publish(this, new DistributionSetTypeEvent(DistributionSetTypeEnum.SELECT_ALL)); + getEventBus().publish(this, + new DistributionSetTableEvent(DistributionTableComponentEvent.SELECT_ALL)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java new file mode 100644 index 000000000..d1a5643a1 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java @@ -0,0 +1,25 @@ +package org.eclipse.hawkbit.ui.distributions.event; + +public class DistributionSetTableEvent { + + private final DistributionTableComponentEvent distributionSetTableEvent; + + /** + * The component event. + * + * @param distributionSetTableEvent + * the distributionSet component event. + */ + public DistributionSetTableEvent(final DistributionTableComponentEvent distributionSetTableEvent) { + this.distributionSetTableEvent = distributionSetTableEvent; + } + + /** + * DistributionSet table components events. + * + */ + public enum DistributionTableComponentEvent { + SELECT_ALL + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java index 3df0a7dd3..c6a625b10 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTypeEvent.java @@ -19,7 +19,7 @@ public class DistributionSetTypeEvent { * DistributionSet type events in the Distribution UI. */ public enum DistributionSetTypeEnum { - ADD_DIST_SET_TYPE, DELETE_DIST_SET_TYPE, UPDATE_DIST_SET_TYPE, ON_VALUE_CHANGE, SELECT_ALL + ADD_DIST_SET_TYPE, DELETE_DIST_SET_TYPE, UPDATE_DIST_SET_TYPE, ON_VALUE_CHANGE } private DistributionSetType distributionSetType; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java index f722c3a23..772afd927 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java @@ -8,36 +8,20 @@ */ package org.eclipse.hawkbit.ui.distributions.event; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEvent; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; - /** - * Class which contains the Event when selecting all entries of a table + * Class which contains the Event when selecting all entries of the + * softwareModule table */ -public class SoftwareModuleTableEvent extends BaseEntityEvent { +public class SoftwareModuleTableEvent { /** * SoftwareModule table components events. - * */ public enum SoftwareModuleComponentEvent { SELECT_ALL } - private SoftwareModuleComponentEvent softwareModuleComponentEvent; - - /** - * Constructor. - * - * @param eventType - * the event type. - * @param entity - * the entity - */ - public SoftwareModuleTableEvent(final BaseEntityEventType eventType, final SoftwareModule entity) { - super(eventType, entity); - } + private final SoftwareModuleComponentEvent softwareModuleComponentEvent; /** * The component event. @@ -46,7 +30,6 @@ public class SoftwareModuleTableEvent extends BaseEntityEvent { * the softwareModule component event. */ public SoftwareModuleTableEvent(final SoftwareModuleComponentEvent softwareModuleComponentEvent) { - super(null, null); this.softwareModuleComponentEvent = softwareModuleComponentEvent; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java index 213dda654..2cd34d3fa 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java @@ -11,8 +11,8 @@ package org.eclipse.hawkbit.ui.management.dstable; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; -import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; -import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent.DistributionTableComponentEvent; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent; +import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent.DistributionTableComponentEvent; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.event.Action; @@ -73,7 +73,8 @@ public class DistributionTableLayout extends AbstractTableLayout { public void handleAction(final Action action, final Object sender, final Object target) { if (ACTION_CTRL_A.equals(action)) { dsTable.selectAll(); - getEventBus().publish(this, new DistributionTableEvent(DistributionTableComponentEvent.SELECT_ALL)); + getEventBus().publish(this, + new DistributionSetTableEvent(DistributionTableComponentEvent.SELECT_ALL)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTableEvent.java index e60f432e7..c35942682 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTableEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/DistributionTableEvent.java @@ -13,20 +13,11 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEvent; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; /** - * - * - * + * Class which contains the Event when selecting all entries of the + * distributions table */ public class DistributionTableEvent extends BaseEntityEvent { - /** - * DistributionSet table components events. - * - */ - public enum DistributionTableComponentEvent { - SELECT_ALL - } - /** * Constructor. * @@ -39,14 +30,4 @@ public class DistributionTableEvent extends BaseEntityEvent { super(eventType, entity); } - /** - * The component event. - * - * @param DistributionSetTableEvent - * the distributionSet component event. - */ - public DistributionTableEvent(final DistributionTableComponentEvent distributionComponentEvent) { - super(null, null); - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java index 04dd917a9..4cfbeecf5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java @@ -13,9 +13,7 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEvent; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; /** - * - * - * + * Class which contains the Event when selecting all entries of the target table */ public class TargetTableEvent extends BaseEntityEvent { From 23b00999e66a72b7619e22df131a5a4aadcf1dc7 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 14 Jun 2016 11:02:16 +0200 Subject: [PATCH 11/82] fix softwaremodule Event Signed-off-by: Melanie Retter --- .../hawkbit/ui/artifacts/event/SoftwareModuleEvent.java | 2 +- .../ui/artifacts/smtable/SoftwareModuleTableLayout.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java index c01257154..95770cb8f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java @@ -23,7 +23,7 @@ public class SoftwareModuleEvent extends BaseEntityEvent { * */ public enum SoftwareModuleEventType { - ARTIFACTS_CHANGED, ASSIGN_SOFTWARE_MODULE, SELECT_ALL + ARTIFACTS_CHANGED, ASSIGN_SOFTWARE_MODULE } private SoftwareModuleEventType softwareModuleEventType; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java index ec6b41e23..a0ed1b4ec 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java @@ -10,9 +10,9 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import javax.annotation.PostConstruct; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; -import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; +import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent; +import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent.SoftwareModuleComponentEvent; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.event.Action; @@ -73,7 +73,7 @@ public class SoftwareModuleTableLayout extends AbstractTableLayout { public void handleAction(final Action action, final Object sender, final Object target) { if (ACTION_CTRL_A.equals(action)) { smTable.selectAll(); - getEventBus().publish(this, new SoftwareModuleEvent(SoftwareModuleEventType.SELECT_ALL, null)); + getEventBus().publish(this, new SoftwareModuleTableEvent(SoftwareModuleComponentEvent.SELECT_ALL)); } } From c3f2c4fc70bb582ae61fe5a73eaffe8474c8d086 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 14 Jun 2016 13:24:58 +0200 Subject: [PATCH 12/82] Refactor multiselect code Signed-off-by: Melanie Retter --- .../smtable/SoftwareModuleTableLayout.java | 40 +---------------- .../table/AbstractNamedVersionTable.java | 8 ---- .../ui/common/table/AbstractTable.java | 8 ++++ .../ui/common/table/AbstractTableLayout.java | 27 ++++++++++-- .../dstable/DistributionSetTableLayout.java | 43 ++----------------- .../event/DistributionSetTableEvent.java | 25 ----------- .../event/SoftwareModuleTableEvent.java | 40 ----------------- .../smtable/SwModuleTableLayout.java | 42 ++---------------- .../dstable/DistributionTableLayout.java | 41 +----------------- .../ui/management/event/TargetTableEvent.java | 2 +- .../management/footer/CountMessageLabel.java | 2 +- .../targettable/TargetTableLayout.java | 39 ++--------------- 12 files changed, 47 insertions(+), 270 deletions(-) delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java index a0ed1b4ec..2672c4546 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java @@ -11,12 +11,8 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; -import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent; -import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent.SoftwareModuleComponentEvent; import org.springframework.beans.factory.annotation.Autowired; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -46,41 +42,9 @@ public class SoftwareModuleTableLayout extends AbstractTableLayout { super.init(smTableHeader, smTable, softwareModuleDetails); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * isShortCutKeysRequired() - */ @Override - protected boolean isShortCutKeysRequired() { - return true; + protected void publishEvent() { + // nothing to publish } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * getShortCutKeysHandler() - */ - @Override - protected Handler getShortCutKeysHandler() { - return new Handler() { - - private static final long serialVersionUID = 1L; - - @Override - public void handleAction(final Action action, final Object sender, final Object target) { - if (ACTION_CTRL_A.equals(action)) { - smTable.selectAll(); - getEventBus().publish(this, new SoftwareModuleTableEvent(SoftwareModuleComponentEvent.SELECT_ALL)); - } - } - - @Override - public Action[] getActions(final Object target, final Object sender) { - return new Action[] { ACTION_CTRL_A }; - } - }; - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java index 3122841ae..ae185a70f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractNamedVersionTable.java @@ -54,12 +54,4 @@ public abstract class AbstractNamedVersionTable extends Table { } } + /** + * Select all rows in the table. + */ + protected void selectAll() { + // only contains the ItemIds of the visible items in the table + setValue(getItemIds()); + } + private void setColumnProperties() { final List columnList = getTableVisibleColumns(); final List swColumnIds = new ArrayList<>(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java index 9406dcb93..b85006468 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java @@ -12,6 +12,7 @@ import org.eclipse.hawkbit.ui.common.detailslayout.AbstractTableDetailsLayout; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; +import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; import com.vaadin.event.ShortcutAction; import com.vaadin.ui.Alignment; @@ -89,10 +90,10 @@ public abstract class AbstractTableLayout extends VerticalLayout { /** * If any short cut keys required on the table. * - * @return true if required else false. Default is 'false'. + * @return true if required else false. Default is 'true'. */ protected boolean isShortCutKeysRequired() { - return false; + return true; } /** @@ -101,7 +102,27 @@ public abstract class AbstractTableLayout extends VerticalLayout { * @return reference of {@link Handler} to handler the short cut keys. * Default is null. */ - protected abstract Handler getShortCutKeysHandler(); + protected Handler getShortCutKeysHandler() { + return new Handler() { + + private static final long serialVersionUID = 1L; + + @Override + public void handleAction(final Action action, final Object sender, final Object target) { + if (ACTION_CTRL_A.equals(action)) { + table.selectAll(); + publishEvent(); + } + } + + @Override + public Action[] getActions(final Object target, final Object sender) { + return new Action[] { ACTION_CTRL_A }; + } + }; + } + + protected abstract void publishEvent(); public void setShowFilterButtonVisible(final boolean visible) { tableHeader.setFilterButtonsIconVisible(visible); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java index cf365b081..66c8aff0e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java @@ -11,17 +11,13 @@ package org.eclipse.hawkbit.ui.distributions.dstable; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent.DistributionTableComponentEvent; import org.springframework.beans.factory.annotation.Autowired; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; /** - * DistributionSet table layout. + * DistributionSet table layout */ @SpringComponent @ViewScope @@ -50,42 +46,9 @@ public class DistributionSetTableLayout extends AbstractTableLayout { super.init(dsTableHeader, dsTable, distributionDetails); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * isShortCutKeysRequired() - */ @Override - protected boolean isShortCutKeysRequired() { - return true; + protected void publishEvent() { + // nothing to publish } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * getShortCutKeysHandler() - */ - @Override - protected Handler getShortCutKeysHandler() { - return new Handler() { - - private static final long serialVersionUID = 1L; - - @Override - public void handleAction(final Action action, final Object sender, final Object target) { - if (ACTION_CTRL_A.equals(action)) { - dsTable.selectAll(); - getEventBus().publish(this, - new DistributionSetTableEvent(DistributionTableComponentEvent.SELECT_ALL)); - } - } - - @Override - public Action[] getActions(final Object target, final Object sender) { - return new Action[] { ACTION_CTRL_A }; - } - }; - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java deleted file mode 100644 index d1a5643a1..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/DistributionSetTableEvent.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.eclipse.hawkbit.ui.distributions.event; - -public class DistributionSetTableEvent { - - private final DistributionTableComponentEvent distributionSetTableEvent; - - /** - * The component event. - * - * @param distributionSetTableEvent - * the distributionSet component event. - */ - public DistributionSetTableEvent(final DistributionTableComponentEvent distributionSetTableEvent) { - this.distributionSetTableEvent = distributionSetTableEvent; - } - - /** - * DistributionSet table components events. - * - */ - public enum DistributionTableComponentEvent { - SELECT_ALL - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java deleted file mode 100644 index 772afd927..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/SoftwareModuleTableEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.distributions.event; - -/** - * Class which contains the Event when selecting all entries of the - * softwareModule table - */ -public class SoftwareModuleTableEvent { - - /** - * SoftwareModule table components events. - */ - public enum SoftwareModuleComponentEvent { - SELECT_ALL - } - - private final SoftwareModuleComponentEvent softwareModuleComponentEvent; - - /** - * The component event. - * - * @param softwareModuleComponentEvent - * the softwareModule component event. - */ - public SoftwareModuleTableEvent(final SoftwareModuleComponentEvent softwareModuleComponentEvent) { - this.softwareModuleComponentEvent = softwareModuleComponentEvent; - } - - public SoftwareModuleComponentEvent getSoftwareModuleComponentEvent() { - return softwareModuleComponentEvent; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java index b2fab5cc9..e0d4b8ac6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java @@ -11,17 +11,13 @@ package org.eclipse.hawkbit.ui.distributions.smtable; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; -import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent; -import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleTableEvent.SoftwareModuleComponentEvent; import org.springframework.beans.factory.annotation.Autowired; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; /** - * Implementation of software module Layout . + * Implementation of software module Layout */ @SpringComponent @ViewScope @@ -46,41 +42,9 @@ public class SwModuleTableLayout extends AbstractTableLayout { super.init(swModuleTableHeader, swModuleTable, swModuleDetails); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * isShortCutKeysRequired() - */ @Override - protected boolean isShortCutKeysRequired() { - return true; + protected void publishEvent() { + // nothing to publish } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * getShortCutKeysHandler() - */ - @Override - protected Handler getShortCutKeysHandler() { - return new Handler() { - - private static final long serialVersionUID = 1L; - - @Override - public void handleAction(final Action action, final Object sender, final Object target) { - if (ACTION_CTRL_A.equals(action)) { - swModuleTable.selectAll(); - getEventBus().publish(this, new SoftwareModuleTableEvent(SoftwareModuleComponentEvent.SELECT_ALL)); - } - } - - @Override - public Action[] getActions(final Object target, final Object sender) { - return new Action[] { ACTION_CTRL_A }; - } - }; - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java index 2cd34d3fa..fefbca972 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java @@ -11,12 +11,8 @@ package org.eclipse.hawkbit.ui.management.dstable; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.common.table.AbstractTableLayout; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent; -import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTableEvent.DistributionTableComponentEvent; import org.springframework.beans.factory.annotation.Autowired; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -46,42 +42,9 @@ public class DistributionTableLayout extends AbstractTableLayout { super.init(dsTableHeader, dsTable, distributionDetails); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * isShortCutKeysRequired() - */ @Override - protected boolean isShortCutKeysRequired() { - return true; + protected void publishEvent() { + // nothing to publish } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * getShortCutKeysHandler() - */ - @Override - protected Handler getShortCutKeysHandler() { - return new Handler() { - - private static final long serialVersionUID = 1L; - - @Override - public void handleAction(final Action action, final Object sender, final Object target) { - if (ACTION_CTRL_A.equals(action)) { - dsTable.selectAll(); - getEventBus().publish(this, - new DistributionSetTableEvent(DistributionTableComponentEvent.SELECT_ALL)); - } - } - - @Override - public Action[] getActions(final Object target, final Object sender) { - return new Action[] { ACTION_CTRL_A }; - } - }; - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java index 4cfbeecf5..214d12106 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/event/TargetTableEvent.java @@ -22,7 +22,7 @@ public class TargetTableEvent extends BaseEntityEvent { * */ public enum TargetComponentEvent { - REFRESH_TARGETS, SELLECT_ALL, BULK_TARGET_CREATED, BULK_UPLOAD_COMPLETED, BULK_TARGET_UPLOAD_STARTED, BULK_UPLOAD_PROCESS_STARTED + REFRESH_TARGETS, SELECT_ALL, BULK_TARGET_CREATED, BULK_UPLOAD_COMPLETED, BULK_TARGET_UPLOAD_STARTED, BULK_UPLOAD_PROCESS_STARTED } private TargetComponentEvent targetComponentEvent; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java index ed6d033bd..fccee7cb5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java @@ -95,7 +95,7 @@ public class CountMessageLabel extends Label { @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final TargetTableEvent event) { - if (TargetTableEvent.TargetComponentEvent.SELLECT_ALL == event.getTargetComponentEvent() + if (TargetTableEvent.TargetComponentEvent.SELECT_ALL == event.getTargetComponentEvent() || TargetComponentEvent.REFRESH_TARGETS == event.getTargetComponentEvent()) { displayTargetCountStatus(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java index 2bd86868c..8c3ec3a1a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableLayout.java @@ -16,8 +16,6 @@ import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentE import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; -import com.vaadin.event.Action; -import com.vaadin.event.Action.Handler; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -47,45 +45,14 @@ public class TargetTableLayout extends AbstractTableLayout { */ @PostConstruct void init() { + super.init(targetTableHeader, targetTable, targetDetails); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * isShortCutKeysRequired() - */ @Override - protected boolean isShortCutKeysRequired() { - return true; - } + protected void publishEvent() { - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.common.table.AbstractTableLayout# - * getShortCutKeysHandler() - */ - @Override - protected Handler getShortCutKeysHandler() { - return new Handler() { - - private static final long serialVersionUID = 1L; - - @Override - public void handleAction(final Action action, final Object sender, final Object target) { - if (ACTION_CTRL_A.equals(action)) { - targetTable.selectAll(); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.SELLECT_ALL)); - } - } - - @Override - public Action[] getActions(final Object target, final Object sender) { - return new Action[] { ACTION_CTRL_A }; - } - }; + eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.SELECT_ALL)); } } From 2b33f3646b5f221556a4af92a381292affe3f755 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 14 Jun 2016 13:28:29 +0200 Subject: [PATCH 13/82] remove EventBus from AbstractTableLayout Signed-off-by: Melanie Retter --- .../hawkbit/ui/common/table/AbstractTableLayout.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java index b85006468..98874626d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.common.table; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractTableDetailsLayout; import org.springframework.beans.factory.annotation.Autowired; -import org.vaadin.spring.events.EventBus; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; @@ -33,9 +32,6 @@ public abstract class AbstractTableLayout extends VerticalLayout { protected static final ShortcutAction ACTION_CTRL_A = new ShortcutAction("Select All", ShortcutAction.KeyCode.A, new int[] { ShortcutAction.ModifierKey.CTRL }); - @Autowired - private transient EventBus.SessionEventBus eventBus; - private AbstractTableHeader tableHeader; private AbstractTable table; @@ -128,8 +124,4 @@ public abstract class AbstractTableLayout extends VerticalLayout { tableHeader.setFilterButtonsIconVisible(visible); } - public EventBus.SessionEventBus getEventBus() { - return eventBus; - } - } From e35ef0f7db8f780c03045d6a60e69c386621a694 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 14 Jun 2016 19:10:21 +0200 Subject: [PATCH 14/82] only select all rows if table is multiselect Signed-off-by: Melanie Retter --- .../org/eclipse/hawkbit/ui/common/table/AbstractTable.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java index 89e8be799..1121ac8a7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java @@ -157,8 +157,10 @@ public abstract class AbstractTable extends Table { * Select all rows in the table. */ protected void selectAll() { - // only contains the ItemIds of the visible items in the table - setValue(getItemIds()); + if (isMultiSelect()) { + // only contains the ItemIds of the visible items in the table + setValue(getItemIds()); + } } private void setColumnProperties() { From ecd56474382d73ca9e628d916cefb5b93c06874b Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 15 Jun 2016 10:45:34 +0200 Subject: [PATCH 15/82] extends mgmt simulator. Extended scalabaility of dmf listener. Signed-off-by: Kai Zimmermann --- .../simulator/amqp/AmqpConfiguration.java | 45 +++++--- .../hawkbit/simulator/amqp/SenderService.java | 22 +++- .../simulator/amqp/SpReceiverService.java | 11 +- .../{logback.xml => logback-spring.xml} | 4 +- .../hawkbit/mgmt/client/Application.java | 9 +- .../client/ClientConfigurationProperties.java | 31 +++++ .../scenarios/ConfigurableScenario.java | 108 ++++++++++++++++-- .../src/main/resources/application.properties | 14 +-- .../{logback.xml => logback-spring.xml} | 0 .../hawkbit/amqp/AmqpConfiguration.java | 7 ++ .../eclipse/hawkbit/amqp/AmqpProperties.java | 15 ++- .../mgmt/rest/api/MgmtTargetRestApi.java | 83 +++++++------- .../mgmt/rest/resource/MgmtTargetMapper.java | 5 +- .../rest/resource/MgmtTargetResource.java | 66 +++++------ .../java/org/eclipse/hawkbit/util/IpUtil.java | 16 ++- 15 files changed, 315 insertions(+), 121 deletions(-) rename examples/hawkbit-device-simulator/src/main/resources/{logback.xml => logback-spring.xml} (94%) rename examples/hawkbit-example-mgmt-simulator/src/main/resources/{logback.xml => logback-spring.xml} (100%) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java index e954cec96..57d4762b0 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java @@ -12,6 +12,8 @@ import java.time.Duration; import java.util.HashMap; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; @@ -22,42 +24,53 @@ import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; -import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.retry.backoff.ExponentialBackOffPolicy; +import org.springframework.retry.support.RetryTemplate; /** * The spring AMQP configuration to use a AMQP for communication with SP update * server. - * - * - * */ @Configuration @EnableConfigurationProperties(AmqpProperties.class) public class AmqpConfiguration { + private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class); + @Autowired protected AmqpProperties amqpProperties; @Autowired private ConnectionFactory connectionFactory; - @Autowired - private RabbitTemplate rabbitTemplate; - /** - * Create jackson message converter bean. - * - * @return the jackson message converter + * @return {@link RabbitTemplate} with automatic retry, published confirms + * and {@link Jackson2JsonMessageConverter}. */ @Bean - public MessageConverter jsonMessageConverter() { - final Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter(); - rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter); - return jackson2JsonMessageConverter; + public RabbitTemplate rabbitTemplate() { + final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); + rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter()); + + final RetryTemplate retryTemplate = new RetryTemplate(); + retryTemplate.setBackOffPolicy(new ExponentialBackOffPolicy()); + rabbitTemplate.setRetryTemplate(retryTemplate); + + rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> { + if (ack) { + LOGGER.debug("Message with correlation ID {} confirmed by broker.", correlationData.getId()); + } else { + LOGGER.error("Broker is unable to handle message with correlation ID {} : {}", correlationData.getId(), + cause); + } + + }); + + return rabbitTemplate; } /** @@ -138,8 +151,8 @@ public class AmqpConfiguration { final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory(); containerFactory.setDefaultRequeueRejected(false); containerFactory.setConnectionFactory(connectionFactory); - containerFactory.setConcurrentConsumers(20); - containerFactory.setMaxConcurrentConsumers(20); + containerFactory.setConcurrentConsumers(3); + containerFactory.setMaxConcurrentConsumers(10); containerFactory.setPrefetchCount(20); return containerFactory; } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java index 6ed6ff0cb..6f16ac736 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java @@ -8,9 +8,14 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import java.util.UUID; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbit.support.CorrelationData; import org.springframework.amqp.support.converter.AbstractJavaTypeMapper; import org.springframework.beans.factory.annotation.Autowired; @@ -22,6 +27,8 @@ import org.springframework.beans.factory.annotation.Autowired; */ public abstract class SenderService extends MessageService { + private static final Logger LOGGER = LoggerFactory.getLogger(SenderService.class); + /** * Constructor for sender service. * @@ -40,18 +47,25 @@ public abstract class SenderService extends MessageService { /** * Send a message if the message is not null. * - * @param adress + * @param address * the exchange name * @param message * the amqp message which will be send if its not null */ - public void sendMessage(final String adress, final Message message) { + public void sendMessage(final String address, final Message message) { if (message == null) { return; } message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME); - rabbitTemplate.setExchange(adress); - rabbitTemplate.send(message); + final String correlationId = UUID.randomUUID().toString(); + + if (LOGGER.isTraceEnabled()) { + LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, address, correlationId); + } else { + LOGGER.debug("Sending message to exchange {} with correlationId {}", address, correlationId); + } + + rabbitTemplate.send(address, null, message, new CorrelationData(correlationId)); } /** diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java index e06b2baf3..4f2981be1 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java @@ -35,14 +35,21 @@ import com.google.common.collect.Lists; public class SpReceiverService extends ReceiverService { private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class); - public static final String SOFTWARE_MODULE_FIRMWARE = "firmware"; - private final SpSenderService spSenderService; private final DeviceSimulatorUpdater deviceUpdater; /** * Constructor. + * + * @param rabbitTemplate + * for sending messages + * @param amqpProperties + * for amqp configuration + * @param spSenderService + * to send messages + * @param deviceUpdater + * simulator service for updates */ @Autowired public SpReceiverService(final RabbitTemplate rabbitTemplate, final AmqpProperties amqpProperties, diff --git a/examples/hawkbit-device-simulator/src/main/resources/logback.xml b/examples/hawkbit-device-simulator/src/main/resources/logback-spring.xml similarity index 94% rename from examples/hawkbit-device-simulator/src/main/resources/logback.xml rename to examples/hawkbit-device-simulator/src/main/resources/logback-spring.xml index 469c7bde3..f25a61cd1 100644 --- a/examples/hawkbit-device-simulator/src/main/resources/logback.xml +++ b/examples/hawkbit-device-simulator/src/main/resources/logback-spring.xml @@ -19,7 +19,9 @@ - + + + diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java index 036c19ed1..e89f3211b 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java @@ -48,7 +48,7 @@ public class Application implements CommandLineRunner { private ClientConfigurationProperties configuration; @Autowired - private ConfigurableScenario configurableScenario; + private ConfigurableScenario configuredScenario; @Autowired private CreateStartedRolloutExample gettingStartedRolloutScenario; @@ -63,9 +63,8 @@ public class Application implements CommandLineRunner { // run the create and start rollout example gettingStartedRolloutScenario.run(); } else { - // run the getting started scenario which creates a setup of - // distribution set and software modules to be used - configurableScenario.run(); + // run the configured scenario from properties + configuredScenario.run(); } } @@ -107,4 +106,4 @@ public class Application implements CommandLineRunner { } return false; } -} \ No newline at end of file +} diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java index cc5fe27e9..8a5c61575 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java @@ -39,8 +39,13 @@ public class ClientConfigurationProperties { private final List scenarios = new ArrayList<>(); + /** + * Simulation {@link Scenario}. + * + */ public static class Scenario { private String tenant = "DEFAULT"; + private boolean cleanRepository; private int targets = 100; private int distributionSets = 10; private int appModulesPerDistributionSet = 2; @@ -50,6 +55,8 @@ public class ClientConfigurationProperties { private String targetName = "Device"; private int artifactsPerSM = 1; private String targetAddress = "amqp:/simulator.replyTo"; + private boolean runRollouts = true; + private int rolloutDeploymentGroups = 4; /** * Artifact size. Values can use the suffixed "MB" or "KB" to indicate a @@ -57,6 +64,30 @@ public class ClientConfigurationProperties { */ private String artifactSize = "1MB"; + public boolean isCleanRepository() { + return cleanRepository; + } + + public void setCleanRepository(final boolean cleanRepository) { + this.cleanRepository = cleanRepository; + } + + public int getRolloutDeploymentGroups() { + return rolloutDeploymentGroups; + } + + public void setRolloutDeploymentGroups(final int rolloutDeploymentGroups) { + this.rolloutDeploymentGroups = rolloutDeploymentGroups; + } + + public boolean isRunRollouts() { + return runRollouts; + } + + public void setRunRollouts(final boolean runRollouts) { + this.runRollouts = runRollouts; + } + public String getTargetAddress() { return targetAddress; } diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java index 60144a88e..84b3da6ee 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. +x * Copyright (c) 2015 Bosch Software Innovations GmbH and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -10,20 +10,25 @@ package org.eclipse.hawkbit.mgmt.client.scenarios; import java.util.List; import java.util.Random; +import java.util.concurrent.TimeUnit; import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties; import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario; import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtRolloutClientResource; import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; -import org.eclipse.hawkbit.mgmt.client.resource.MgmtSystemManagementClientResource; import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource; import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.RolloutBuilder; import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder; import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder; import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder; import org.eclipse.hawkbit.mgmt.client.scenarios.upload.ArtifactFile; +import org.eclipse.hawkbit.mgmt.json.model.PagedList; import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; +import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody; import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule; +import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -53,7 +58,7 @@ public class ConfigurableScenario { private MgmtTargetClientResource targetResource; @Autowired - private MgmtSystemManagementClientResource systemManagementResource; + private MgmtRolloutClientResource rolloutResource; @Autowired private ClientConfigurationProperties clientConfigurationProperties; @@ -65,16 +70,93 @@ public class ConfigurableScenario { LOGGER.info("Running Configurable Scenario..."); - clientConfigurationProperties.getScenarios().parallelStream().forEach(this::createScenario); + clientConfigurationProperties.getScenarios().forEach(this::createScenario); } private void createScenario(final Scenario scenario) { - systemManagementResource.deleteTenant(scenario.getTenant()); + if (scenario.isCleanRepository()) { + cleanRepository(); + } + createTargets(scenario); createDistributionSets(scenario); + + if (scenario.isRunRollouts()) { + runRollouts(scenario); + } + } + + private void cleanRepository() { + LOGGER.info("Cleaning repository"); + deleteTargets(); + deleteRollouts(); + deleteDistributionSets(); + deleteSoftwareModules(); + LOGGER.info("Cleaning repository -> Done"); + } + + private void deleteRollouts() { + // TODO: complete this as soon as rollouts can be deleted + + } + + private void deleteSoftwareModules() { + PagedList modules; + do { + modules = softwareModuleResource.getSoftwareModules(0, 100, null, null).getBody(); + modules.getContent().forEach(module -> softwareModuleResource.deleteSoftwareModule(module.getModuleId())); + } while (modules.getTotal() > 100); + } + + private void deleteDistributionSets() { + PagedList distributionSets; + do { + distributionSets = distributionSetResource.getDistributionSets(0, 100, null, null).getBody(); + distributionSets.getContent().forEach(set -> distributionSetResource.deleteDistributionSet(set.getDsId())); + } while (distributionSets.getTotal() > 100); + } + + private void deleteTargets() { + PagedList targets; + do { + targets = targetResource.getTargets(0, 100, null, null).getBody(); + targets.getContent().forEach(target -> targetResource.deleteTarget(target.getControllerId())); + } while (targets.getTotal() > 100); + } + + private void runRollouts(final Scenario scenario) { + distributionSetResource.getDistributionSets(0, scenario.getDistributionSets(), null, null).getBody() + .getContent().forEach(set -> runRollout(set, scenario)); + + } + + private void runRollout(final MgmtDistributionSet set, final Scenario scenario) { + LOGGER.info("Run rollout for set {}", set.getDsId()); + // create a Rollout + final MgmtRolloutResponseBody rolloutResponseBody = rolloutResource + .create(new RolloutBuilder().name("Rollout" + set.getName() + set.getVersion()) + .groupSize(scenario.getRolloutDeploymentGroups()).targetFilterQuery("name==*") + .distributionSetId(set.getDsId()).successThreshold("80").errorThreshold("5").build()) + .getBody(); + + // start the created Rollout + rolloutResource.start(rolloutResponseBody.getRolloutId(), true); + + // wait until rollout is complete + do { + try { + TimeUnit.SECONDS.sleep(35); + } catch (final InterruptedException e) { + LOGGER.warn("Interrupted!"); + Thread.currentThread().interrupt(); + } + } while (targetResource.getTargets(0, 1, null, "updateStatus==IN_SYNC").getBody().getTotal() < scenario + .getTargets()); + LOGGER.info("Run rollout for set {} -> Done", set.getDsId()); } private void createDistributionSets(final Scenario scenario) { + LOGGER.info("Creating {} distribution sets", scenario.getDistributionSets()); final byte[] artifact = generateArtifact(scenario); distributionSetResource @@ -87,6 +169,8 @@ public class ConfigurableScenario { modules.forEach(module -> assign.id(module.getModuleId())); distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build()); }); + + LOGGER.info("Creating {} distribution sets -> Done", scenario.getDistributionSets()); } private List addModules(final Scenario scenario, final MgmtDistributionSet dsSet, @@ -110,8 +194,10 @@ public class ConfigurableScenario { return modules; } - private byte[] generateArtifact(final Scenario scenario) { - // create random object + private static byte[] generateArtifact(final Scenario scenario) { + + // Exception squid:S2245 - not used for cryptographic function + @SuppressWarnings("squid:S2245") final Random random = new Random(); // create byte array @@ -124,14 +210,18 @@ public class ConfigurableScenario { } private void createTargets(final Scenario scenario) { + LOGGER.info("Creating {} targets", scenario.getTargets()); + for (int i = 0; i < scenario.getTargets() / 100; i++) { targetResource.createTargets(new TargetBuilder().controllerId(scenario.getTargetName()) .address(scenario.getTargetAddress()).buildAsList(i * 100, - (i + 1) * 100 > scenario.getTargets() ? scenario.getTargets() - i * 100 : 100)); + (i + 1) * 100 > scenario.getTargets() ? (scenario.getTargets() - (i * 100)) : 100)); } + + LOGGER.info("Creating {} targets -> Done", scenario.getTargets()); } - private int parseSize(final String s) { + private static int parseSize(final String s) { final String size = s.toUpperCase(); if (size.endsWith("KB")) { return Integer.valueOf(size.substring(0, size.length() - 2)) * 1024; diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties index f538bb1cb..e19b83e19 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties @@ -13,12 +13,8 @@ hawkbit.password=admin spring.main.show-banner=false -#hawkbit.scenarios.[0].targets=0 -#hawkbit.scenarios.[0].ds-name=gettingstarted-example -#hawkbit.scenarios.[0].distribution-sets=3 -#hawkbit.scenarios.[0].sm-fw-name=gettingstarted-example -#hawkbit.scenarios.[0].sm-sw-name=gettingstarted-example - -hawkbit.scenarios.[0].targets=10000 -hawkbit.scenarios.[0].distribution-sets=100 -hawkbit.scenarios.[0].artifactsPerSM=0 \ No newline at end of file +hawkbit.scenarios.[0].targets=0 +hawkbit.scenarios.[0].ds-name=gettingstarted-example +hawkbit.scenarios.[0].distribution-sets=3 +hawkbit.scenarios.[0].sm-fw-name=gettingstarted-example +hawkbit.scenarios.[0].sm-sw-name=gettingstarted-example \ No newline at end of file diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/resources/logback.xml b/examples/hawkbit-example-mgmt-simulator/src/main/resources/logback-spring.xml similarity index 100% rename from examples/hawkbit-example-mgmt-simulator/src/main/resources/logback.xml rename to examples/hawkbit-example-mgmt-simulator/src/main/resources/logback-spring.xml diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 541ae414c..3fbc6aee2 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.support.RetryTemplate;; @@ -58,6 +59,9 @@ public class AmqpConfiguration { @Autowired private ConnectionFactory rabbitConnectionFactory; + @Autowired + private TaskExecutor taskExecutor; + @Configuration protected static class RabbitConnectionFactoryCreator { @@ -240,6 +244,9 @@ public class AmqpConfiguration { containerFactory.setDefaultRequeueRejected(false); containerFactory.setConnectionFactory(rabbitConnectionFactory); containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); + containerFactory.setTaskExecutor(taskExecutor); + containerFactory.setConcurrentConsumers(3); + containerFactory.setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers()); return containerFactory; } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java index f9b4cceb6..a20c59792 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java @@ -38,13 +38,26 @@ public class AmqpProperties { /** * Missing queue fatal. */ - private boolean missingQueuesFatal = false; + private boolean missingQueuesFatal; /** * Requested heartbeat interval from broker in {@link TimeUnit#SECONDS}. */ private int requestedHeartBeat = (int) TimeUnit.SECONDS.toSeconds(60); + /** + * Sets an upper limit to the number of consumers. + */ + private int maxConcurrentConsumers = 10; + + public int getMaxConcurrentConsumers() { + return maxConcurrentConsumers; + } + + public void setMaxConcurrentConsumers(final int maxConcurrentConsumers) { + this.maxConcurrentConsumers = maxConcurrentConsumers; + } + /** * Is missingQueuesFatal enabled * diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java index bf4e169a0..97a0eae5c 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java @@ -35,14 +35,14 @@ public interface MgmtTargetRestApi { /** * Handles the GET request of retrieving a single target. * - * @param targetId + * @param controllerId * the ID of the target to retrieve * @return a single target with status OK. */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}", produces = { "application/hal+json", + @RequestMapping(method = RequestMethod.GET, value = "/{controllerId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity getTarget(@PathVariable("targetId") final String targetId); + ResponseEntity getTarget(@PathVariable("controllerId") final String controllerId); /** * Handles the GET request of retrieving all targets. @@ -91,7 +91,7 @@ public interface MgmtTargetRestApi { * path of the request. A given ID in the request body is ignored. It's not * possible to set fields to {@code null} values. * - * @param targetId + * @param controllerId * the path parameter which contains the ID of the target * @param targetRest * the request body which contains the fields which should be @@ -100,40 +100,40 @@ public interface MgmtTargetRestApi { * @return the updated target response which contains all fields also fields * which have not updated */ - @RequestMapping(method = RequestMethod.PUT, value = "/{targetId}", consumes = { "application/hal+json", + @RequestMapping(method = RequestMethod.PUT, value = "/{controllerId}", consumes = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity updateTarget(@PathVariable("targetId") final String targetId, + ResponseEntity updateTarget(@PathVariable("controllerId") final String controllerId, @RequestBody final MgmtTargetRequestBody targetRest); /** * Handles the DELETE request of deleting a target. * - * @param targetId + * @param controllerId * the ID of the target to be deleted - * @return If the given targetId could exists and could be deleted Http OK. - * In any failure the JsonResponseExceptionHandler is handling the - * response. + * @return If the given controllerId could exists and could be deleted Http + * OK. In any failure the JsonResponseExceptionHandler is handling + * the response. */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}", produces = { "application/hal+json", + @RequestMapping(method = RequestMethod.DELETE, value = "/{controllerId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity deleteTarget(@PathVariable("targetId") final String targetId); + ResponseEntity deleteTarget(@PathVariable("controllerId") final String controllerId); /** * Handles the GET request of retrieving the attributes of a specific * target. * - * @param targetId + * @param controllerId * the ID of the target to retrieve the attributes. * @return the target attributes as map response with status OK */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/attributes", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity getAttributes(@PathVariable("targetId") final String targetId); + @RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/attributes", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + ResponseEntity getAttributes(@PathVariable("controllerId") final String controllerId); /** * Handles the GET request of retrieving the Actions of a specific target. * - * @param targetId + * @param controllerId * to load actions for * @param pagingOffsetParam * the offset of list of targets for pagination, might not be @@ -151,9 +151,9 @@ public interface MgmtTargetRestApi { * status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions", produces = { "application/hal+json", + @RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/actions", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity> getActionHistory(@PathVariable("targetId") final String targetId, + ResponseEntity> getActionHistory(@PathVariable("controllerId") final String controllerId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, @@ -163,22 +163,22 @@ public interface MgmtTargetRestApi { * Handles the GET request of retrieving a specific Actions of a specific * Target. * - * @param targetId + * @param controllerId * to load the action for * @param actionId * to load * @return the action */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}", produces = { + @RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/actions/{actionId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity getAction(@PathVariable("targetId") final String targetId, + ResponseEntity getAction(@PathVariable("controllerId") final String controllerId, @PathVariable("actionId") final Long actionId); /** * Handles the DELETE request of canceling an specific Actions of a specific * Target. * - * @param targetId + * @param controllerId * the ID of the target in the URL path parameter * @param actionId * the ID of the action in the URL path parameter @@ -186,8 +186,8 @@ public interface MgmtTargetRestApi { * optional parameter, which indicates a force cancel * @return status no content in case cancellation was successful */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}/actions/{actionId}") - ResponseEntity cancelAction(@PathVariable("targetId") final String targetId, + @RequestMapping(method = RequestMethod.DELETE, value = "/{controllerId}/actions/{actionId}") + ResponseEntity cancelAction(@PathVariable("controllerId") final String controllerId, @PathVariable("actionId") final Long actionId, @RequestParam(value = "force", required = false, defaultValue = "false") final boolean force); @@ -195,7 +195,7 @@ public interface MgmtTargetRestApi { * Handles the GET request of retrieving the ActionStatus of a specific * target and action. * - * @param targetId + * @param controllerId * of the the action * @param actionId * of the status we are intend to load @@ -212,10 +212,10 @@ public interface MgmtTargetRestApi { * with status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}/status", produces = { + @RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/actions/{actionId}/status", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity> getActionStatusList(@PathVariable("targetId") final String targetId, - @PathVariable("actionId") final Long actionId, + ResponseEntity> getActionStatusList( + @PathVariable("controllerId") final String controllerId, @PathVariable("actionId") final Long actionId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam); @@ -224,40 +224,43 @@ public interface MgmtTargetRestApi { * Handles the GET request of retrieving the assigned distribution set of an * specific target. * - * @param targetId + * @param controllerId * the ID of the target to retrieve the assigned distribution * @return the assigned distribution set with status OK, if none is assigned * than {@code null} content (e.g. "{}") */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/assignedDS", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity getAssignedDistributionSet(@PathVariable("targetId") final String targetId); + @RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/assignedDS", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + ResponseEntity getAssignedDistributionSet( + @PathVariable("controllerId") final String controllerId); /** * Changes the assigned distribution set of a target. * - * @param targetId + * @param controllerId * of the target to change * @param dsId * of the distributionset that is to be assigned * @return http status */ - @RequestMapping(method = RequestMethod.POST, value = "/{targetId}/assignedDS", consumes = { "application/hal+json", + @RequestMapping(method = RequestMethod.POST, value = "/{controllerId}/assignedDS", consumes = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity postAssignedDistributionSet(@PathVariable("targetId") final String targetId, + ResponseEntity postAssignedDistributionSet(@PathVariable("controllerId") final String controllerId, @RequestBody final MgmtDistributionSetAssigment dsId); /** * Handles the GET request of retrieving the installed distribution set of * an specific target. * - * @param targetId + * @param controllerId * the ID of the target to retrieve * @return the assigned installed set with status OK, if none is installed * than {@code null} content (e.g. "{}") */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/installedDS", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity getInstalledDistributionSet(@PathVariable("targetId") final String targetId); + @RequestMapping(method = RequestMethod.GET, value = "/{controllerId}/installedDS", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + ResponseEntity getInstalledDistributionSet( + @PathVariable("controllerId") final String controllerId); } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index d77cbaa53..f6cf9f54b 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -32,6 +32,7 @@ import org.eclipse.hawkbit.repository.model.PollStatus; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.rest.data.SortDirection; +import org.eclipse.hawkbit.util.IpUtil; /** * A mapper which maps repository model to RESTful model representation and @@ -141,7 +142,9 @@ public final class MgmtTargetMapper { final URI address = target.getTargetInfo().getAddress(); if (address != null) { - targetRest.setIpAddress(address.getHost()); + if (IpUtil.isIpAddresKnown(address)) { + targetRest.setIpAddress(address.getHost()); + } targetRest.setAddress(address.toString()); } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java index cc7bbcde6..c41dadd27 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java @@ -68,8 +68,8 @@ public class MgmtTargetResource implements MgmtTargetRestApi { private EntityFactory entityFactory; @Override - public ResponseEntity getTarget(@PathVariable("targetId") final String targetId) { - final Target findTarget = findTargetWithExceptionIfNotFound(targetId); + public ResponseEntity getTarget(@PathVariable("controllerId") final String controllerId) { + final Target findTarget = findTargetWithExceptionIfNotFound(controllerId); // to single response include poll status final MgmtTarget response = MgmtTargetMapper.toResponse(findTarget); MgmtTargetMapper.addPollStatus(findTarget, response); @@ -115,9 +115,9 @@ public class MgmtTargetResource implements MgmtTargetRestApi { } @Override - public ResponseEntity updateTarget(@PathVariable("targetId") final String targetId, + public ResponseEntity updateTarget(@PathVariable("controllerId") final String controllerId, @RequestBody final MgmtTargetRequestBody targetRest) { - final Target existingTarget = findTargetWithExceptionIfNotFound(targetId); + final Target existingTarget = findTargetWithExceptionIfNotFound(controllerId); LOG.debug("updating target {}", existingTarget.getId()); if (targetRest.getDescription() != null) { existingTarget.setDescription(targetRest.getDescription()); @@ -131,16 +131,16 @@ public class MgmtTargetResource implements MgmtTargetRestApi { } @Override - public ResponseEntity deleteTarget(@PathVariable("targetId") final String targetId) { - final Target target = findTargetWithExceptionIfNotFound(targetId); + public ResponseEntity deleteTarget(@PathVariable("controllerId") final String controllerId) { + final Target target = findTargetWithExceptionIfNotFound(controllerId); this.targetManagement.deleteTargets(target.getId()); - LOG.debug("{} target deleted, return status {}", targetId, HttpStatus.OK); + LOG.debug("{} target deleted, return status {}", controllerId, HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK); } @Override - public ResponseEntity getAttributes(@PathVariable("targetId") final String targetId) { - final Target foundTarget = findTargetWithExceptionIfNotFound(targetId); + public ResponseEntity getAttributes(@PathVariable("controllerId") final String controllerId) { + final Target foundTarget = findTargetWithExceptionIfNotFound(controllerId); final Map controllerAttributes = foundTarget.getTargetInfo().getControllerAttributes(); if (controllerAttributes.isEmpty()) { return new ResponseEntity<>(HttpStatus.NO_CONTENT); @@ -153,13 +153,14 @@ public class MgmtTargetResource implements MgmtTargetRestApi { } @Override - public ResponseEntity> getActionHistory(@PathVariable("targetId") final String targetId, + public ResponseEntity> getActionHistory( + @PathVariable("controllerId") final String controllerId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { - final Target foundTarget = findTargetWithExceptionIfNotFound(targetId); + final Target foundTarget = findTargetWithExceptionIfNotFound(controllerId); final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); @@ -177,14 +178,15 @@ public class MgmtTargetResource implements MgmtTargetRestApi { } return new ResponseEntity<>( - new PagedList<>(MgmtTargetMapper.toResponse(targetId, activeActions.getContent()), totalActionCount), + new PagedList<>(MgmtTargetMapper.toResponse(controllerId, activeActions.getContent()), + totalActionCount), HttpStatus.OK); } @Override - public ResponseEntity getAction(@PathVariable("targetId") final String targetId, + public ResponseEntity getAction(@PathVariable("controllerId") final String controllerId, @PathVariable("actionId") final Long actionId) { - final Target target = findTargetWithExceptionIfNotFound(targetId); + final Target target = findTargetWithExceptionIfNotFound(controllerId); final Action action = findActionWithExceptionIfNotFound(actionId); if (!action.getTarget().getId().equals(target.getId())) { @@ -192,18 +194,18 @@ public class MgmtTargetResource implements MgmtTargetRestApi { return new ResponseEntity<>(HttpStatus.NOT_FOUND); } - final MgmtAction result = MgmtTargetMapper.toResponse(targetId, action, action.isActive()); + final MgmtAction result = MgmtTargetMapper.toResponse(controllerId, action, action.isActive()); if (!action.isCancelingOrCanceled()) { result.add(linkTo( methodOn(MgmtDistributionSetRestApi.class).getDistributionSet(action.getDistributionSet().getId())) .withRel("distributionset")); } else if (action.isCancelingOrCanceled()) { - result.add(linkTo(methodOn(MgmtTargetRestApi.class).getAction(targetId, action.getId())) + result.add(linkTo(methodOn(MgmtTargetRestApi.class).getAction(controllerId, action.getId())) .withRel(MgmtRestConstants.TARGET_V1_CANCELED_ACTION)); } - result.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionStatusList(targetId, action.getId(), 0, + result.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionStatusList(controllerId, action.getId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, ActionStatusFields.ID.getFieldName() + ":" + SortDirection.DESC)) .withRel(MgmtRestConstants.TARGET_V1_ACTION_STATUS)); @@ -212,10 +214,10 @@ public class MgmtTargetResource implements MgmtTargetRestApi { } @Override - public ResponseEntity cancelAction(@PathVariable("targetId") final String targetId, + public ResponseEntity cancelAction(@PathVariable("controllerId") final String controllerId, @PathVariable("actionId") final Long actionId, @RequestParam(value = "force", required = false, defaultValue = "false") final boolean force) { - final Target target = findTargetWithExceptionIfNotFound(targetId); + final Target target = findTargetWithExceptionIfNotFound(controllerId); final Action action = findActionWithExceptionIfNotFound(actionId); if (force) { @@ -231,12 +233,12 @@ public class MgmtTargetResource implements MgmtTargetRestApi { @Override public ResponseEntity> getActionStatusList( - @PathVariable("targetId") final String targetId, @PathVariable("actionId") final Long actionId, + @PathVariable("controllerId") final String controllerId, @PathVariable("actionId") final Long actionId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam) { - final Target target = findTargetWithExceptionIfNotFound(targetId); + final Target target = findTargetWithExceptionIfNotFound(controllerId); final Action action = findActionWithExceptionIfNotFound(actionId); if (!action.getTarget().getId().equals(target.getId())) { @@ -260,8 +262,8 @@ public class MgmtTargetResource implements MgmtTargetRestApi { @Override public ResponseEntity getAssignedDistributionSet( - @PathVariable("targetId") final String targetId) { - final Target findTarget = findTargetWithExceptionIfNotFound(targetId); + @PathVariable("controllerId") final String controllerId) { + final Target findTarget = findTargetWithExceptionIfNotFound(controllerId); final MgmtDistributionSet distributionSetRest = MgmtDistributionSetMapper .toResponse(findTarget.getAssignedDistributionSet()); final HttpStatus retStatus; @@ -274,29 +276,29 @@ public class MgmtTargetResource implements MgmtTargetRestApi { } @Override - public ResponseEntity postAssignedDistributionSet(@PathVariable("targetId") final String targetId, + public ResponseEntity postAssignedDistributionSet(@PathVariable("controllerId") final String controllerId, @RequestBody final MgmtDistributionSetAssigment dsId) { - findTargetWithExceptionIfNotFound(targetId); + findTargetWithExceptionIfNotFound(controllerId); final ActionType type = (dsId.getType() != null) ? MgmtRestModelMapper.convertActionType(dsId.getType()) : ActionType.FORCED; final Iterator changed = this.deploymentManagement - .assignDistributionSet(dsId.getId(), type, dsId.getForcetime(), targetId).getAssignedEntity() + .assignDistributionSet(dsId.getId(), type, dsId.getForcetime(), controllerId).getAssignedEntity() .iterator(); if (changed.hasNext()) { return new ResponseEntity<>(HttpStatus.OK); } LOG.error("Target update (ds {} assigment to target {}) failed! Returnd target list is empty.", dsId.getId(), - targetId); + controllerId); return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } @Override public ResponseEntity getInstalledDistributionSet( - @PathVariable("targetId") final String targetId) { - final Target findTarget = findTargetWithExceptionIfNotFound(targetId); + @PathVariable("controllerId") final String controllerId) { + final Target findTarget = findTargetWithExceptionIfNotFound(controllerId); final MgmtDistributionSet distributionSetRest = MgmtDistributionSetMapper .toResponse(findTarget.getTargetInfo().getInstalledDistributionSet()); final HttpStatus retStatus; @@ -308,10 +310,10 @@ public class MgmtTargetResource implements MgmtTargetRestApi { return new ResponseEntity<>(distributionSetRest, retStatus); } - private Target findTargetWithExceptionIfNotFound(final String targetId) { - final Target findTarget = this.targetManagement.findTargetByControllerID(targetId); + private Target findTargetWithExceptionIfNotFound(final String controllerId) { + final Target findTarget = this.targetManagement.findTargetByControllerID(controllerId); if (findTarget == null) { - throw new EntityNotFoundException("Target with Id {" + targetId + "} does not exist"); + throw new EntityNotFoundException("Target with Id {" + controllerId + "} does not exist"); } return findTarget; } diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java index 96fc557aa..c7778f776 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/util/IpUtil.java @@ -26,6 +26,7 @@ import com.google.common.net.HttpHeaders; */ public final class IpUtil { + private static final String HIDDEN_IP = "***"; private static final String SCHEME_SEPERATOR = "://"; private static final String HTTP_SCHEME = "http"; private static final String AMPQP_SCHEME = "amqp"; @@ -87,7 +88,7 @@ public final class IpUtil { ip = request.getRemoteAddr(); } } else { - ip = "***"; + ip = HIDDEN_IP; } return createHttpUri(ip); @@ -178,4 +179,17 @@ public final class IpUtil { public static boolean isAmqpUri(final URI uri) { return uri != null && AMPQP_SCHEME.equals(uri.getScheme()); } + + /** + * Check if the IP address of that {@link URI} is known, i.e. not an AQMP + * exchange in DMF case and not HIDDEN_IP in DDI case. + * + * @param uri + * the uri + * @return true if IP address is actually known by the server + */ + public static boolean isIpAddresKnown(final URI uri) { + return uri != null && !(AMPQP_SCHEME.equals(uri.getScheme()) || HIDDEN_IP.equals(uri.getHost())); + } + } From 4e91b87aed4cbd90437eee9d01b166ca08cb86af Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 15 Jun 2016 11:10:29 +0200 Subject: [PATCH 16/82] mandatoryLabel inserted in content Signed-off-by: Melanie Retter --- .../smtable/SoftwareModuleAddUpdateWindow.java | 8 +++++++- .../hawkbit/ui/common/CommonDialogWindow.java | 18 +++++++++++++++--- .../layouts/AbstractCreateUpdateTagLayout.java | 4 ++++ .../TargetAddUpdateWindowLayout.java | 4 ++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 85b55d69d..7fe8e25de 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -92,6 +92,8 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private Long baseSwModuleId; + private FormLayout formLayout; + /** * Create window for new software module. * @@ -207,7 +209,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se */ addStyleName("lay-color"); - final FormLayout formLayout = new FormLayout(); + formLayout = new FormLayout(); formLayout.setCaption(null); formLayout.addComponent(typeComboBox); formLayout.addComponent(nameTextField); @@ -369,4 +371,8 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se return !(event.getText().equals(oldVendorValue) && descTextArea.getValue().equals(oldDescriptionValue)); } + public FormLayout getFormLayout() { + return formLayout; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 754f61ed2..d3153ee9a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -14,8 +14,11 @@ import java.io.Serializable; import java.util.Map; import org.apache.commons.lang3.StringUtils; +import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleBorderWithIcon; +import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout; +import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -224,9 +227,18 @@ public class CommonDialogWindow extends Window implements Serializable { if (existsMandatoryFieldsInWindowContent()) { // final Label madatoryLabel = new // Label(i18n.get("label.mandatory.field")); - final Label madatoryLabel = new Label("* Mandatory Field"); - madatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); - mainLayout.addComponent(madatoryLabel); + final Label mandatoryLabel = new Label("* Mandatory Field"); + mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); + + if (content instanceof TargetAddUpdateWindowLayout) { + ((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof SoftwareModuleAddUpdateWindow) { + ((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof AbstractCreateUpdateTagLayout) { + ((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel); + } + + mainLayout.addComponent(mandatoryLabel); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index f8fb5c3e0..85847ccc5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -690,4 +690,8 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent this.tagDescOriginal = tagDescOriginal; } + public GridLayout getMainLayout() { + return mainLayout; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index e5d65295b..287df14b3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -334,4 +334,8 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { window.addStyleName("target-update-window"); } + public FormLayout getFormLayout() { + return formLayout; + } + } From c3d04a530f03afbec2e29fc2bd849d3febb98965 Mon Sep 17 00:00:00 2001 From: Jonathan Knoblauch Date: Wed, 15 Jun 2016 13:45:50 +0200 Subject: [PATCH 17/82] Changed f to F --- .../hawkbit/ui/management/targettable/TargetTableHeader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java index 5b0aa285a..16dc584ed 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java @@ -398,7 +398,7 @@ public class TargetTableHeader extends AbstractTableHeader { getFilterDroppedInfo().setSizeFull(); getFilterDroppedInfo().addComponent(filteredDistLabel); getFilterDroppedInfo().addComponent(filterLabelClose); - getFilterDroppedInfo().setExpandRatio(filteredDistLabel, 1.0f); + getFilterDroppedInfo().setExpandRatio(filteredDistLabel, 1.0F); eventbus.publish(this, TargetFilterEvent.FILTER_BY_DISTRIBUTION); } From 20ebbed27f773235ea41c778d5f7dfac1c3ec42d Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Fri, 17 Jun 2016 11:32:04 +0200 Subject: [PATCH 18/82] Set separate handling for invalid message handling and internal server errors which should result in requeue instead of reject Signed-off-by: kaizimmerm --- .../org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java | 2 +- .../org/eclipse/hawkbit/simulator/amqp/ReceiverService.java | 3 ++- .../main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java | 2 +- .../main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java index 57d4762b0..8ae2d87bd 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java @@ -149,7 +149,7 @@ public class AmqpConfiguration { @Bean(name = { "listenerContainerFactory" }) public SimpleRabbitListenerContainerFactory listenerContainerFactory() { final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory(); - containerFactory.setDefaultRequeueRejected(false); + containerFactory.setDefaultRequeueRejected(true); containerFactory.setConnectionFactory(connectionFactory); containerFactory.setConcurrentConsumers(3); containerFactory.setMaxConcurrentConsumers(10); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/ReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/ReceiverService.java index f5c02789e..2e8833bab 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/ReceiverService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/ReceiverService.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import org.springframework.amqp.AmqpRejectAndDontRequeueException; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.core.RabbitTemplate; @@ -55,7 +56,7 @@ public abstract class ReceiverService extends MessageService { if (contentType != null && contentType.contains("json")) { return; } - throw new IllegalArgumentException("Content-Type is not JSON compatible"); + throw new AmqpRejectAndDontRequeueException("Content-Type is not JSON compatible"); } } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 3fbc6aee2..9435e8860 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -241,7 +241,7 @@ public class AmqpConfiguration { @Bean(name = { "listenerContainerFactory" }) public SimpleRabbitListenerContainerFactory listenerContainerFactory() { final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory(); - containerFactory.setDefaultRequeueRejected(false); + containerFactory.setDefaultRequeueRejected(true); containerFactory.setConnectionFactory(rabbitConnectionFactory); containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); containerFactory.setTaskExecutor(taskExecutor); diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java index 2c8feda13..88c88f264 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java @@ -15,6 +15,7 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.amqp.AmqpRejectAndDontRequeueException; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.support.converter.AbstractJavaTypeMapper; @@ -110,7 +111,7 @@ public class BaseAmqpService { protected final void logAndThrowMessageError(final Message message, final String error) { LOGGER.warn("Warning! \"{}\" reported by message: {}", error, message); - throw new IllegalArgumentException(error); + throw new AmqpRejectAndDontRequeueException(error); } protected RabbitTemplate getRabbitTemplate() { From 581748228edecfacd985d80724aa1da78ee403a3 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Fri, 17 Jun 2016 18:17:48 +0200 Subject: [PATCH 19/82] Distribution Filter by type view: save button enabled when changes exist Signed-off-by: Melanie Retter --- .../CreateUpdateSoftwareTypeLayout.java | 2 +- .../hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../CreateUpdateDistSetTypeLayout.java | 133 ++++++++++++------ .../AbstractCreateUpdateTagLayout.java | 6 +- .../ui/layouts/CreateUpdateTypeLayout.java | 20 +++ 5 files changed, 113 insertions(+), 50 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 7473d5509..c8a0c650e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -103,10 +103,10 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); + tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); singleMultiOptionGroup(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index d3153ee9a..7818953b0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -149,7 +149,7 @@ public class CommonDialogWindow extends Window implements Serializable { public void updateRequiredFields(final String fieldId, final Boolean filled) { - getRequiredFields().put(fieldId, Boolean.TRUE); + getRequiredFields().put(fieldId, filled); checkMandatoryFields(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index a04136a48..facf6e008 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -14,6 +14,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; @@ -87,8 +88,10 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private Table sourceTable; private Table selectedTable; - private IndexedContainer selectedTablecontainer; - private IndexedContainer sourceTablecontainer; + private IndexedContainer selectedTableContainer; + private IndexedContainer sourceTableContainer; + + private IndexedContainer originalSelectedTableContainer; @Override protected void createRequiredComponents() { @@ -114,6 +117,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); + tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); } private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { @@ -175,9 +179,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return twinColumnLayout; } - /** - * - */ private void buildSelectedTable() { selectedTable = new Table(); @@ -192,7 +193,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout selectedTable.addStyleName("dist_type_twin-table"); selectedTable.setSizeFull(); createSelectedTableContainer(); - selectedTable.setContainerDataSource(selectedTablecontainer); + selectedTable.setContainerDataSource(selectedTableContainer); addTooltTipToSelectedTable(); selectedTable.setImmediate(true); selectedTable.setVisibleColumns(DIST_TYPE_NAME, DIST_TYPE_MANDATORY); @@ -234,14 +235,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout sourceTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES); sourceTable.addStyleName(ValoTheme.TABLE_SMALL); sourceTable.setImmediate(true); - // sourceTable sourceTable.setSizeFull(); sourceTable.addStyleName("dist_type_twin-table"); sourceTable.setSortEnabled(false); - sourceTablecontainer = new IndexedContainer(); - sourceTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); - sourceTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); - sourceTable.setContainerDataSource(sourceTablecontainer); + sourceTableContainer = new IndexedContainer(); + sourceTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + sourceTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + sourceTable.setContainerDataSource(sourceTableContainer); sourceTable.setVisibleColumns(new Object[] { DIST_TYPE_NAME }); sourceTable.setColumnHeaders(i18n.get("header.dist.twintable.available")); @@ -253,10 +253,23 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void createSelectedTableContainer() { - selectedTablecontainer = new IndexedContainer(); - selectedTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); - selectedTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); - selectedTablecontainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); + selectedTableContainer = new IndexedContainer(); + selectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + selectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + selectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); + } + + private void listenerMandatoryCheckboxChanged(final ValueChangeEvent event) { + + window.setSaveButtonEnabled(true); + } + + private void createOriginalSelectedTableContainer() { + + originalSelectedTableContainer = new IndexedContainer(); + originalSelectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, ""); + originalSelectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, ""); + originalSelectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null); } @SuppressWarnings("unchecked") @@ -267,8 +280,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addTargetTableData(id); } - - window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); + if (optiongroup.getValue().equals(updateTypeStr)) { + updateMandatoryFields(); + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); + } else { + if (!selectedTableContainer.getItemIds().isEmpty()) { + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); + } + } } } @@ -276,26 +295,57 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @SuppressWarnings("unchecked") final Set selectedIds = (Set) selectedTable.getValue(); - if (null != selectedIds && !selectedIds.isEmpty()) { + if (selectedIds != null && !selectedIds.isEmpty()) { for (final Long id : selectedIds) { addSourceTableData(id); selectedTable.removeItem(id); + if (optiongroup.getValue().equals(updateTypeStr)) { + updateMandatoryFields(); + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); + } } } - if (selectedIds == null || selectedIds.isEmpty()) { - window.updateRequiredFields(selectedTable.getId(), Boolean.FALSE); + } + + private Boolean hasContentChanged() { + + for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { + final long itemId = (Long) itemIterator.next(); + if (!originalSelectedTableContainer.containsId(itemId)) { + return Boolean.TRUE; + } + } + + for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator + .hasNext();) { + final long itemId = (Long) itemIterator.next(); + if (!selectedTableContainer.containsId(itemId)) { + return Boolean.TRUE; + } + } + + return Boolean.FALSE; + } + + private void updateMandatoryFields() { + + if (StringUtils.isNotBlank(tagName.getValue())) { + window.getRequiredFields().put("Name", Boolean.TRUE); + } + if (StringUtils.isNotBlank(typeKey.getValue())) { + window.getRequiredFields().put("Key", Boolean.TRUE); } } @SuppressWarnings("unchecked") private void getSourceTableData() { - sourceTablecontainer.removeAllItems(); + sourceTableContainer.removeAllItems(); final Iterable moduleTypeBeans = softwareManagement .findSoftwareModuleTypesAll(new PageRequest(0, 1_000)); Item saveTblitem; for (final SoftwareModuleType swTypeTag : moduleTypeBeans) { - saveTblitem = sourceTablecontainer.addItem(swTypeTag.getId()); + saveTblitem = sourceTableContainer.addItem(swTypeTag.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swTypeTag.getName()); saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(swTypeTag.getDescription()); } @@ -328,8 +378,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void getSelectedTableItemData(final Long id) { Item saveTblitem; - if (null != selectedTablecontainer) { - saveTblitem = selectedTablecontainer.addItem(id); + if (selectedTableContainer != null) { + saveTblitem = selectedTableContainer.addItem(id); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue( sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue()); saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox()); @@ -341,9 +391,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @SuppressWarnings("unchecked") private void addSourceTableData(final Long selectedId) { - if (null != sourceTablecontainer) { + if (sourceTableContainer != null) { Item saveTblitem; - saveTblitem = sourceTablecontainer.addItem(selectedId); + saveTblitem = sourceTableContainer.addItem(selectedId); selectedTable.getContainerDataSource().getItem(selectedId).getItemProperty(DIST_TYPE_NAME); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource() .getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue()); @@ -387,7 +437,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey")); - } } @@ -432,7 +481,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } - } private void checkMandatoryAndAddMandatoryModuleType(final DistributionSetType updateDistSetType, @@ -461,26 +509,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return distSetType; } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.components.colorpicker.HasColorChangeListener# - * addColorChangeListener(com.vaadin - * .ui.components.colorpicker.ColorChangeListener) - */ @Override public void addColorChangeListener(final ColorChangeListener listener) { LOG.info("in side addColorChangeListener() "); } - /* - * (non-Javadoc) - * - * @see com.vaadin.ui.components.colorpicker.HasColorChangeListener# - * removeColorChangeListener(com. - * vaadin.ui.components.colorpicker.ColorChangeListener) - */ @Override public void removeColorChangeListener(final ColorChangeListener listener) { @@ -574,7 +608,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setValue(selectedTypeTag.getDescription()); setTagDescOriginal(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); - + setTypeKeyOriginal(selectedTypeTag.getKey()); if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) { distTypeSelectLayout.setEnabled(true); selectedTable.setEnabled(true); @@ -584,6 +618,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout distTypeSelectLayout.setEnabled(false); selectedTable.setEnabled(false); } + + createOriginalSelectedTableContainer(); for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) { addTargetTableforUpdate(swModuleType, false); } @@ -604,11 +640,18 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) { Item saveTblitem; - if (null != selectedTablecontainer) { - saveTblitem = selectedTablecontainer.addItem(swModuleType.getId()); + if (selectedTableContainer != null) { + saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); sourceTable.removeItem(swModuleType.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer + .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); + mandatoryCheckbox.addValueChangeListener(this::listenerMandatoryCheckboxChanged); + + final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); + originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); + originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 85847ccc5..a6fc1accb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -110,7 +110,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; - private Color selectedColorOriginal; + protected Color selectedColorOriginal; private String tagDescOriginal; protected void createWindow() { @@ -189,7 +189,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); @@ -211,7 +210,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent window.checkMandatoryTextField(event, tagName); } - private void listenerTagDescTextAreaChanged(final TextChangeEvent event) { + protected void listenerTagDescTextAreaChanged(final TextChangeEvent event) { window.checkChanges(event.getText(), tagDescOriginal); } @@ -416,6 +415,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent */ protected void createDynamicStyleForComponents(final TextField tagName, final TextArea tagDesc, final String taregtTagColor) { + tagName.removeStyleName(SPUIDefinitions.TAG_NAME); tagDesc.removeStyleName(SPUIDefinitions.TAG_DESC); getTargetDynamicStyles(taregtTagColor); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index c67d35321..f2ef71af1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -45,6 +45,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected String createTypeStr; protected String updateTypeStr; protected TextField typeKey; + protected String typeKeyOriginal; public static final String TYPE_NAME_DYNAMIC_STYLE = "new-tag-name"; private static final String TYPE_DESC_DYNAMIC_STYLE = "new-tag-desc"; @@ -185,6 +186,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } + window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); } /** @@ -321,4 +323,22 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { // is implemented in the inherited class } + @Override + public Color getSelectedColorOriginal() { + return selectedColorOriginal; + } + + @Override + public void setSelectedColorOriginal(final Color selectedColorOriginal) { + this.selectedColorOriginal = selectedColorOriginal; + } + + public String getTypeKeyOriginal() { + return typeKeyOriginal; + } + + public void setTypeKeyOriginal(final String typeKeyOriginal) { + this.typeKeyOriginal = typeKeyOriginal; + } + } From 58b883d773a4da83d76a18ed0eb1f35982b6bc82 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Sun, 19 Jun 2016 20:42:23 +0200 Subject: [PATCH 20/82] Added polling for DMF simulated devices. Signed-off-by: kaizimmerm --- examples/hawkbit-device-simulator/pom.xml | 24 ++---------- .../simulator/AbstractSimulatedDevice.java | 17 ++++++++- .../hawkbit/simulator/DDISimulatedDevice.java | 10 +---- .../hawkbit/simulator/DMFSimulatedDevice.java | 14 ++++++- .../simulator/DeviceSimulatorRepository.java | 4 +- .../simulator/NextPollTimeController.java | 12 +++--- .../simulator/SimulatedDeviceFactory.java | 8 +++- .../simulator/SimulationController.java | 2 +- .../simulator/SimulationProperties.java | 5 ++- .../simulator/amqp/AmqpConfiguration.java | 38 +++++++++++++++++++ .../event/NextPollCounterUpdate.java | 8 ++-- .../hawkbit/simulator/ui/SimulatorView.java | 4 +- .../src/main/resources/application.properties | 1 - .../{logback-spring.xml => logback.xml} | 5 --- 14 files changed, 94 insertions(+), 58 deletions(-) rename examples/hawkbit-device-simulator/src/main/resources/{logback-spring.xml => logback.xml} (86%) diff --git a/examples/hawkbit-device-simulator/pom.xml b/examples/hawkbit-device-simulator/pom.xml index 3c3df9486..035bcebfc 100644 --- a/examples/hawkbit-device-simulator/pom.xml +++ b/examples/hawkbit-device-simulator/pom.xml @@ -71,6 +71,10 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-logging + org.springframework.security spring-security-web @@ -83,26 +87,6 @@ org.springframework.boot spring-boot-starter - - - org.apache.logging.log4j - log4j-api - - - - org.slf4j - jul-to-slf4j - - - - org.slf4j - jcl-over-slf4j - - - - org.slf4j - log4j-over-slf4j - com.vaadin vaadin-spring-boot-starter diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java index 890f43367..c70d4f584 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java @@ -27,7 +27,7 @@ public abstract class AbstractSimulatedDevice { private UpdateStatus updateStatus = new UpdateStatus(ResponseStatus.SUCCESSFUL, "Simulation complete!"); private Protocol protocol = Protocol.DMF_AMQP; private String targetSecurityToken; - + private int pollDelaySec; private int nextPollCounterSec; /** @@ -84,13 +84,26 @@ public abstract class AbstractSimulatedDevice { * the ID of the simulated device * @param tenant * the tenant of the simulated device + * @param int + * pollDelaySec */ - AbstractSimulatedDevice(final String id, final String tenant, final Protocol protocol) { + AbstractSimulatedDevice(final String id, final String tenant, final Protocol protocol, final int pollDelaySec) { this.id = id; this.tenant = tenant; this.status = Status.UNKNWON; this.progress = 0.0; this.protocol = protocol; + this.pollDelaySec = pollDelaySec; + } + + abstract public void poll(); + + public int getPollDelaySec() { + return pollDelaySec; + } + + public void setPollDelaySec(final int pollDelaySec) { + this.pollDelaySec = pollDelaySec; } /** diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java index 26e613dd9..677d77a37 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DDISimulatedDevice.java @@ -23,7 +23,6 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice { private static final Logger LOGGER = LoggerFactory.getLogger(DDISimulatedDevice.class); - private final int pollDelaySec; private final ControllerResource controllerResource; private final DeviceSimulatorUpdater deviceUpdater; @@ -45,11 +44,9 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice { */ public DDISimulatedDevice(final String id, final String tenant, final int pollDelaySec, final ControllerResource controllerResource, final DeviceSimulatorUpdater deviceUpdater) { - super(id, tenant, Protocol.DDI_HTTP); - this.pollDelaySec = pollDelaySec; + super(id, tenant, Protocol.DDI_HTTP, pollDelaySec); this.controllerResource = controllerResource; this.deviceUpdater = deviceUpdater; - setNextPollCounterSec(pollDelaySec); } @Override @@ -58,13 +55,10 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice { removed = true; } - public int getPollDelaySec() { - return pollDelaySec; - } - /** * Polls the base URL for the DDI API interface. */ + @Override public void poll() { if (!removed) { final String basePollJson = controllerResource.get(getTenant(), getId()); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java index 6b79a85b8..65227b55d 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DMFSimulatedDevice.java @@ -8,10 +8,13 @@ */ package org.eclipse.hawkbit.simulator; +import org.eclipse.hawkbit.simulator.amqp.SpSenderService; + /** * A simulated device using the DMF API of the hawkBit update server. */ public class DMFSimulatedDevice extends AbstractSimulatedDevice { + private final SpSenderService spSenderService; /** * @param id @@ -19,8 +22,15 @@ public class DMFSimulatedDevice extends AbstractSimulatedDevice { * @param tenant * the tenant of the simulated device */ - public DMFSimulatedDevice(final String id, final String tenant) { - super(id, tenant, Protocol.DMF_AMQP); + public DMFSimulatedDevice(final String id, final String tenant, final SpSenderService spSenderService, + final int pollDelaySec) { + super(id, tenant, Protocol.DMF_AMQP, pollDelaySec); + this.spSenderService = spSenderService; + } + + @Override + public void poll() { + spSenderService.createOrUpdateThing(super.getTenant(), super.getId()); } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorRepository.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorRepository.java index 68db9df45..66ceacc8e 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorRepository.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorRepository.java @@ -9,8 +9,8 @@ package org.eclipse.hawkbit.simulator; import java.util.Collection; -import java.util.LinkedHashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -25,7 +25,7 @@ import org.springframework.stereotype.Service; @Service public class DeviceSimulatorRepository { - private final Map devices = new LinkedHashMap<>(); + private final Map devices = new ConcurrentHashMap<>(); @Autowired private SimulatedDeviceFactory deviceFactory; diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java index 956d6d36a..96b4a1e97 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/NextPollTimeController.java @@ -8,12 +8,11 @@ */ package org.eclipse.hawkbit.simulator; -import java.util.List; +import java.util.Collection; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate; import org.slf4j.Logger; @@ -51,18 +50,17 @@ public class NextPollTimeController { private class NextPollUpdaterRunnable implements Runnable { @Override public void run() { - final List devices = repository.getAll().stream() - .filter(device -> device instanceof DDISimulatedDevice).collect(Collectors.toList()); + final Collection devices = repository.getAll(); devices.forEach(device -> { int nextCounter = device.getNextPollCounterSec() - 1; - if (nextCounter < 0 && device instanceof DDISimulatedDevice) { + if (nextCounter < 0) { try { - pollService.submit(() -> ((DDISimulatedDevice) device).poll()); + pollService.submit(() -> device.poll()); } catch (final IllegalStateException e) { LOGGER.trace("Device could not be polled", e); } - nextCounter = ((DDISimulatedDevice) device).getPollDelaySec(); + nextCounter = device.getPollDelaySec(); } device.setNextPollCounterSec(nextCounter); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java index f29aad001..35829c673 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.simulator; import java.net.URL; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; +import org.eclipse.hawkbit.simulator.amqp.SpSenderService; import org.eclipse.hawkbit.simulator.http.ControllerResource; import org.eclipse.hawkbit.simulator.http.GatewayTokenInterceptor; import org.springframework.beans.factory.annotation.Autowired; @@ -28,6 +29,9 @@ public class SimulatedDeviceFactory { @Autowired private DeviceSimulatorUpdater deviceUpdater; + @Autowired + private SpSenderService spSenderService; + /** * Creating a simulated devices. * @@ -55,7 +59,7 @@ public class SimulatedDeviceFactory { * the protocol which should be used be the simulated device * @param pollDelaySec * the poll delay time in seconds which should be used for - * {@link DDISimulatedDevice}s + * {@link DDISimulatedDevice}s and {@link DMFSimulatedDevice} * @param baseEndpoint * the http base endpoint which should be used for * {@link DDISimulatedDevice}s @@ -68,7 +72,7 @@ public class SimulatedDeviceFactory { final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) { switch (protocol) { case DMF_AMQP: - return new DMFSimulatedDevice(id, tenant); + return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec); case DDI_HTTP: final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger()) .requestInterceptor(new GatewayTokenInterceptor(gatewayToken)).logLevel(Logger.Level.BASIC) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java index 649d88477..3bd6b41f2 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java @@ -66,7 +66,7 @@ public class SimulationController { @RequestParam(value = "tenant", defaultValue = "DEFAULT") final String tenant, @RequestParam(value = "api", defaultValue = "dmf") final String api, @RequestParam(value = "endpoint", defaultValue = "http://localhost:8080") final String endpoint, - @RequestParam(value = "polldelay", defaultValue = "30") final int pollDelay, + @RequestParam(value = "polldelay", defaultValue = "1800") final int pollDelay, @RequestParam(value = "gatewaytoken", defaultValue = "") final String gatewayToken) throws MalformedURLException { diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationProperties.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationProperties.java index 354263934..fb98ff67e 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationProperties.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationProperties.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.simulator; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; import org.hibernate.validator.constraints.NotEmpty; @@ -68,9 +69,9 @@ public class SimulationProperties { private String endpoint = "http://localhost:8080"; /** - * Poll time in case of DDI API based simulation. + * Poll time in {@link TimeUnit#SECONDS} for simulated devices. */ - private int pollDelay = 30; + private int pollDelay = (int) TimeUnit.MINUTES.toSeconds(30); /** * Optional gateway token for DDI API based simulation. diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java index 8ae2d87bd..5be5c7dcb 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java @@ -20,11 +20,13 @@ import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.QueueBuilder; import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.amqp.RabbitProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -73,6 +75,42 @@ public class AmqpConfiguration { return rabbitTemplate; } + @Configuration + protected static class RabbitConnectionFactoryCreator { + + /** + * {@link ConnectionFactory} with enabled publisher confirms and + * heartbeat. + * + * @param config + * with standard {@link RabbitProperties} + * @return {@link ConnectionFactory} + */ + @Bean + public ConnectionFactory rabbitConnectionFactory(final RabbitProperties config) { + final CachingConnectionFactory factory = new CachingConnectionFactory(); + factory.setRequestedHeartBeat(60); + factory.setPublisherConfirms(true); + + final String addresses = config.getAddresses(); + factory.setAddresses(addresses); + if (config.getHost() != null) { + factory.setHost(config.getHost()); + factory.setPort(config.getPort()); + } + if (config.getUsername() != null) { + factory.setUsername(config.getUsername()); + } + if (config.getPassword() != null) { + factory.setPassword(config.getPassword()); + } + if (config.getVirtualHost() != null) { + factory.setVirtualHost(config.getVirtualHost()); + } + return factory; + } + } + /** * Creates the receiver queue from update server for receiving message from * update server. diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/NextPollCounterUpdate.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/NextPollCounterUpdate.java index b9d7b9027..5e98ebb64 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/NextPollCounterUpdate.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/event/NextPollCounterUpdate.java @@ -8,7 +8,7 @@ */ package org.eclipse.hawkbit.simulator.event; -import java.util.List; +import java.util.Collection; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice; @@ -20,7 +20,7 @@ import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice; */ public class NextPollCounterUpdate { - private final List devices; + private final Collection devices; /** * Creates poll timer update event. @@ -28,14 +28,14 @@ public class NextPollCounterUpdate { * @param devices * the devices which progress has been updated */ - public NextPollCounterUpdate(final List devices) { + public NextPollCounterUpdate(final Collection devices) { this.devices = devices; } /** * @return the devices of the event */ - public List getDevices() { + public Collection getDevices() { return devices; } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 4834bece9..9405edd2b 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -8,7 +8,7 @@ */ package org.eclipse.hawkbit.simulator.ui; -import java.util.List; +import java.util.Collection; import java.util.Locale; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice; @@ -167,7 +167,7 @@ public class SimulatorView extends VerticalLayout implements View { @SuppressWarnings("unchecked") @Subscribe public void pollCounterUpdate(final NextPollCounterUpdate update) { - final List devices = update.getDevices(); + final Collection devices = update.getDevices(); this.getUI().access(() -> devices.forEach(device -> { final BeanItem item = beanContainer.getItem(device.getId()); if (item != null) { diff --git a/examples/hawkbit-device-simulator/src/main/resources/application.properties b/examples/hawkbit-device-simulator/src/main/resources/application.properties index fbe7261be..5d3f04be7 100644 --- a/examples/hawkbit-device-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-device-simulator/src/main/resources/application.properties @@ -24,7 +24,6 @@ spring.rabbitmq.virtualHost=/ spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.dynamic=true -spring.rabbitmq.listener.prefetch=100 security.basic.enabled=false server.port=8083 diff --git a/examples/hawkbit-device-simulator/src/main/resources/logback-spring.xml b/examples/hawkbit-device-simulator/src/main/resources/logback.xml similarity index 86% rename from examples/hawkbit-device-simulator/src/main/resources/logback-spring.xml rename to examples/hawkbit-device-simulator/src/main/resources/logback.xml index f25a61cd1..5f3f1dbef 100644 --- a/examples/hawkbit-device-simulator/src/main/resources/logback-spring.xml +++ b/examples/hawkbit-device-simulator/src/main/resources/logback.xml @@ -20,11 +20,6 @@ - - - - - From cc1dc0951602b02a8f7f5d25bff13ecedd62c576 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Sun, 19 Jun 2016 20:43:12 +0200 Subject: [PATCH 21/82] Configurable prefetch and consumer pool. Signed-off-by: kaizimmerm --- hawkbit-dmf-amqp/pom.xml | 10 +++++++ .../hawkbit/amqp/AmqpConfiguration.java | 12 +++----- .../amqp/AmqpMessageHandlerService.java | 25 +++++++++-------- .../eclipse/hawkbit/amqp/AmqpProperties.java | 28 +++++++++++++++++++ .../amqp/AmqpMessageHandlerServiceTest.java | 17 +++++------ 5 files changed, 65 insertions(+), 27 deletions(-) diff --git a/hawkbit-dmf-amqp/pom.xml b/hawkbit-dmf-amqp/pom.xml index c2ed7c213..322dd5047 100644 --- a/hawkbit-dmf-amqp/pom.xml +++ b/hawkbit-dmf-amqp/pom.xml @@ -49,6 +49,11 @@ org.springframework.amqp spring-rabbit + + com.rabbitmq + amqp-client + 3.6.2 + org.springframework.security spring-security-web @@ -154,6 +159,11 @@ spring-context-support test + + org.scala-lang + scala-library + 2.10.4 + \ No newline at end of file diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 9435e8860..0e7e766e8 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -32,7 +32,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.task.TaskExecutor; import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.support.RetryTemplate;; @@ -59,9 +58,6 @@ public class AmqpConfiguration { @Autowired private ConnectionFactory rabbitConnectionFactory; - @Autowired - private TaskExecutor taskExecutor; - @Configuration protected static class RabbitConnectionFactoryCreator { @@ -201,8 +197,8 @@ public class AmqpConfiguration { } /** - * Create the Binding {@link AmqpConfiguration#receiverQueueFromSp()} to - * {@link AmqpConfiguration#senderConnectorToSpExchange()}. + * Create the Binding {@link AmqpConfiguration#receiverQueue()} to + * {@link AmqpConfiguration#senderExchange()}. * * @return the binding and create the queue and exchange */ @@ -244,9 +240,9 @@ public class AmqpConfiguration { containerFactory.setDefaultRequeueRejected(true); containerFactory.setConnectionFactory(rabbitConnectionFactory); containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); - containerFactory.setTaskExecutor(taskExecutor); - containerFactory.setConcurrentConsumers(3); + containerFactory.setConcurrentConsumers(amqpProperties.getInitialConcurrentConsumers()); containerFactory.setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers()); + containerFactory.setPrefetchCount(amqpProperties.getPrefetchCount()); return containerFactory; } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 107850fc1..caa11ab3d 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -37,6 +37,7 @@ import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.TenantNotExistException; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; @@ -47,6 +48,7 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.util.IpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.amqp.AmqpRejectAndDontRequeueException; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.annotation.RabbitListener; @@ -111,12 +113,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService { super(defaultTemplate); } - @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue}", containerFactory = "listenerContainerFactory") - private Message onMessage(final Message message, @Header(MessageHeaderKey.TYPE) final String type, - @Header(MessageHeaderKey.TENANT) final String tenant) { - return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost()); - } - /** * Method to handle all incoming amqp messages. * @@ -124,14 +120,17 @@ public class AmqpMessageHandlerService extends BaseAmqpService { * incoming message * @param type * the message type - * @param contentType - * the contentType of the message * @param tenant * the contentType of the message - * @param virtualHost - * the virtual host + * * @return a message if no message is send back to sender */ + @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue}", containerFactory = "listenerContainerFactory") + public Message onMessage(final Message message, @Header(MessageHeaderKey.TYPE) final String type, + @Header(MessageHeaderKey.TENANT) final String tenant) { + return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost()); + } + public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) { checkContentTypeJson(message); final SecurityContext oldContext = SecurityContextHolder.getContext(); @@ -153,6 +152,10 @@ public class AmqpMessageHandlerService extends BaseAmqpService { default: logAndThrowMessageError(message, "No handle method was found for the given message type."); } + } catch (final IllegalArgumentException ex) { + throw new AmqpRejectAndDontRequeueException("Invalid message!", ex); + } catch (final TenantNotExistException teex) { + throw new AmqpRejectAndDontRequeueException(teex); } finally { SecurityContextHolder.setContext(oldContext); } @@ -421,7 +424,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } } - private void checkContentTypeJson(final Message message) { + private static void checkContentTypeJson(final Message message) { final MessageProperties messageProperties = message.getMessageProperties(); if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) { return; diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java index a20c59792..ace1fefa2 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java @@ -50,6 +50,34 @@ public class AmqpProperties { */ private int maxConcurrentConsumers = 10; + /** + * Tells the broker how many messages to send to each consumer in a single + * request. Often this can be set quite high to improve throughput. + */ + private int prefetchCount = 10; + + /** + * Initial number of consumers. Is scaled up if necessary up to + * {@link #maxConcurrentConsumers}. + */ + private int initialConcurrentConsumers = 3; + + public int getPrefetchCount() { + return prefetchCount; + } + + public void setPrefetchCount(final int prefetchCount) { + this.prefetchCount = prefetchCount; + } + + public int getInitialConcurrentConsumers() { + return initialConcurrentConsumers; + } + + public void setInitialConcurrentConsumers(final int initialConcurrentConsumers) { + this.initialConcurrentConsumers = initialConcurrentConsumers; + } + public int getMaxConcurrentConsumers() { return maxConcurrentConsumers; } diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index a0515a871..338feea62 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -59,6 +59,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.springframework.amqp.AmqpRejectAndDontRequeueException; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.core.RabbitTemplate; @@ -170,7 +171,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted since no replyTo header was set"); - } catch (final IllegalArgumentException exception) { + } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -184,7 +185,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted since no thingID was set"); - } catch (final IllegalArgumentException exception) { + } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } } @@ -200,7 +201,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, type, TENANT, "vHost"); fail("IllegalArgumentException was excepeted due to unknown message type"); - } catch (final IllegalArgumentException exception) { + } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } } @@ -213,21 +214,21 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted due to unknown message type"); - } catch (final IllegalArgumentException e) { + } catch (final AmqpRejectAndDontRequeueException e) { } try { messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic"); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted due to unknown topic"); - } catch (final IllegalArgumentException e) { + } catch (final AmqpRejectAndDontRequeueException e) { } messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name()); try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted because there was no event topic"); - } catch (final IllegalArgumentException exception) { + } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -246,7 +247,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted since no action id was set"); - } catch (final IllegalArgumentException exception) { + } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } } @@ -263,7 +264,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted since no action id was set"); - } catch (final IllegalArgumentException exception) { + } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } From eac44899f2a357c20161afa66e86a8cb476917b3 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Sun, 19 Jun 2016 20:43:47 +0200 Subject: [PATCH 22/82] Completed configurable mgmt simulation scenario. Signed-off-by: kaizimmerm --- .../MgmtDistributionSetClientResource.java | 2 +- .../MgmtDistributionSetTagClientResource.java | 2 +- ...MgmtDistributionSetTypeClientResource.java | 2 +- .../MgmtDownloadArtifactClientResource.java | 2 +- .../resource/MgmtDownloadClientResource.java | 2 +- .../resource/MgmtRolloutClientResource.java | 2 +- .../MgmtSoftwareModuleClientResource.java | 3 ++- .../MgmtSoftwareModuleTypeClientResource.java | 2 +- .../resource/MgmtSystemClientResource.java | 2 +- .../MgmtSystemManagementClientResource.java | 2 +- .../resource/MgmtTargetClientResource.java | 2 +- .../resource/MgmtTargetTagClientResource.java | 2 +- .../builder/SoftwareModuleBuilder.java | 2 +- .../hawkbit/mgmt/client/Application.java | 12 ++++++++--- .../client/ClientConfigurationProperties.java | 9 -------- .../scenarios/ConfigurableScenario.java | 21 +++++++++---------- .../upload/FeignMultipartEncoder.java | 13 ++++++++---- .../src/main/resources/application.properties | 4 +++- .../{logback-spring.xml => logback.xml} | 12 +++-------- .../artifact/repository/ArtifactStore.java | 16 ++++---------- .../ArtifactStoreAutoConfiguration.java | 5 ----- 21 files changed, 52 insertions(+), 67 deletions(-) rename examples/hawkbit-example-mgmt-simulator/src/main/resources/{logback-spring.xml => logback.xml} (57%) diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetClientResource.java index 7bf696a8f..40eb13b55 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetClientResource.java @@ -15,7 +15,7 @@ import org.springframework.cloud.netflix.feign.FeignClient; /** * Client binding for the DistributionSet resource of the management API. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) public interface MgmtDistributionSetClientResource extends MgmtDistributionSetRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTagClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTagClientResource.java index 783cc09fa..1070bbd9c 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTagClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTagClientResource.java @@ -15,6 +15,6 @@ import org.springframework.cloud.netflix.feign.FeignClient; /** * Client binding for the DistributionSetTag resource of the management API. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) public interface MgmtDistributionSetTagClientResource extends MgmtDistributionSetTagRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTypeClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTypeClientResource.java index 35f26781f..451c53942 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTypeClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDistributionSetTypeClientResource.java @@ -16,7 +16,7 @@ import org.springframework.cloud.netflix.feign.FeignClient; * Client binding for the DistributionSetType resource of the management API. * */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING) public interface MgmtDistributionSetTypeClientResource extends MgmtDistributionSetTypeRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadArtifactClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadArtifactClientResource.java index d25a609b2..5c93edce5 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadArtifactClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadArtifactClientResource.java @@ -16,7 +16,7 @@ import org.springframework.cloud.netflix.feign.FeignClient; * A feign-client interface declaration which allows to build a feign-client * stub. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) public interface MgmtDownloadArtifactClientResource extends MgmtDownloadArtifactRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadClientResource.java index 9a1dcee61..330d3908f 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtDownloadClientResource.java @@ -15,6 +15,6 @@ import org.springframework.cloud.netflix.feign.FeignClient; /** * */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE) public interface MgmtDownloadClientResource extends MgmtDownloadRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtRolloutClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtRolloutClientResource.java index d2643a938..acc00d6fe 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtRolloutClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtRolloutClientResource.java @@ -15,6 +15,6 @@ import org.springframework.cloud.netflix.feign.FeignClient; /** * Client binding for the Rollout resource of the management API. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING) public interface MgmtRolloutClientResource extends MgmtRolloutRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleClientResource.java index 16ea188bd..7a2267e24 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleClientResource.java @@ -24,9 +24,10 @@ import feign.Param; /** * Client binding for the SoftwareModule resource of the management API. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) public interface MgmtSoftwareModuleClientResource extends MgmtSoftwareModuleRestApi { + @Override @RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/artifacts") ResponseEntity uploadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, @Param("file") final MultipartFile file, diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleTypeClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleTypeClientResource.java index 1e9462c47..603e82f10 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleTypeClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSoftwareModuleTypeClientResource.java @@ -15,6 +15,6 @@ import org.springframework.cloud.netflix.feign.FeignClient; /** * Client binding for the SoftwareModuleType resource of the management API. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING) public interface MgmtSoftwareModuleTypeClientResource extends MgmtSoftwareModuleTypeRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemClientResource.java index 7d6967fed..e1bbd909c 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemClientResource.java @@ -16,6 +16,6 @@ import org.springframework.cloud.netflix.feign.FeignClient; * Client binding for the {@link MgmtSystemRestApi}. * */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING) public interface MgmtSystemClientResource extends MgmtSystemRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemManagementClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemManagementClientResource.java index d1974b43f..802194fe8 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemManagementClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtSystemManagementClientResource.java @@ -16,7 +16,7 @@ import org.springframework.cloud.netflix.feign.FeignClient; * Client binding for the {@link MgmtSystemManagementRestApi}. * */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.SYSTEM_ADMIN_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.SYSTEM_ADMIN_MAPPING) public interface MgmtSystemManagementClientResource extends MgmtSystemManagementRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetClientResource.java index 872c4251a..c0a0193af 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetClientResource.java @@ -15,6 +15,6 @@ import org.springframework.cloud.netflix.feign.FeignClient; /** * Client binding for the Target resource of the management API. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING) public interface MgmtTargetClientResource extends MgmtTargetRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetTagClientResource.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetTagClientResource.java index 7b0c213af..3f9264337 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetTagClientResource.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/MgmtTargetTagClientResource.java @@ -15,6 +15,6 @@ import org.springframework.cloud.netflix.feign.FeignClient; /** * Client binding for the TargetTag resource of the management API. */ -@FeignClient(url = "${hawkbit.url:localhost:8080}/" + MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING) +@FeignClient(url = "${hawkbit.url:localhost:8080}" + MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING) public interface MgmtTargetTagClientResource extends MgmtTargetTagRestApi { } diff --git a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java index 1d633e440..db7941bfc 100644 --- a/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java +++ b/examples/hawkbit-example-mgmt-feign-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java @@ -90,7 +90,7 @@ public class SoftwareModuleBuilder { * @return a single entry list of {@link MgmtSoftwareModuleRequestBodyPost} */ public List build() { - return Lists.newArrayList(doBuild(name)); + return Lists.newArrayList(doBuild("")); } /** diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java index e89f3211b..8ebd8830a 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java @@ -35,9 +35,10 @@ import feign.Feign; import feign.Logger; import feign.auth.BasicAuthRequestInterceptor; import feign.jackson.JacksonDecoder; +import feign.slf4j.Slf4jLogger; @SpringBootApplication -@EnableFeignClients +@EnableFeignClients("org.eclipse.hawkbit.mgmt.client.resource") @EnableConfigurationProperties(ClientConfigurationProperties.class) @Configuration @AutoConfigureAfter(FeignClientConfiguration.class) @@ -83,6 +84,11 @@ public class Application implements CommandLineRunner { return new CreateStartedRolloutExample(); } + @Bean + public Logger.Level feignLoggerLevel() { + return Logger.Level.FULL; + } + @Bean public MgmtSoftwareModuleClientResource uploadSoftwareModule() { final ObjectMapper mapper = new ObjectMapper() @@ -92,13 +98,13 @@ public class Application implements CommandLineRunner { return Feign.builder().contract(new IgnoreMultipleConsumersProducersSpringMvcContract()) .requestInterceptor( new BasicAuthRequestInterceptor(configuration.getUsername(), configuration.getPassword())) - .logger(new Logger.ErrorLogger()).encoder(new FeignMultipartEncoder()) + .logger(new Slf4jLogger()).encoder(new FeignMultipartEncoder()) .decoder(new ResponseEntityDecoder(new JacksonDecoder(mapper))) .target(MgmtSoftwareModuleClientResource.class, configuration.getUrl() + MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING); } - private boolean containsArg(final String containsArg, final String... args) { + private static boolean containsArg(final String containsArg, final String... args) { for (final String arg : args) { if (arg.equalsIgnoreCase(containsArg)) { return true; diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java index 8a5c61575..83a0844d4 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java @@ -44,7 +44,6 @@ public class ClientConfigurationProperties { * */ public static class Scenario { - private String tenant = "DEFAULT"; private boolean cleanRepository; private int targets = 100; private int distributionSets = 10; @@ -96,14 +95,6 @@ public class ClientConfigurationProperties { this.targetAddress = targetAddress; } - public String getTenant() { - return tenant; - } - - public void setTenant(final String tenant) { - this.tenant = tenant; - } - public int getArtifactsPerSM() { return artifactsPerSM; } diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java index 84b3da6ee..240f94568 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java @@ -1,5 +1,5 @@ /** -x * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -159,10 +159,9 @@ public class ConfigurableScenario { LOGGER.info("Creating {} distribution sets", scenario.getDistributionSets()); final byte[] artifact = generateArtifact(scenario); - distributionSetResource - .createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()).type("os_app") - .version("1.0.").buildAsList(scenario.getDistributionSets())) - .getBody().parallelStream().forEach(dsSet -> { + distributionSetResource.createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()) + .type("os_app").version("1.0.").buildAsList(scenario.getDistributionSets())).getBody() + .forEach(dsSet -> { final List modules = addModules(scenario, dsSet, artifact); final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder(); @@ -175,13 +174,13 @@ public class ConfigurableScenario { private List addModules(final Scenario scenario, final MgmtDistributionSet dsSet, final byte[] artifact) { - final List modules = softwareModuleResource.createSoftwareModules( - new SoftwareModuleBuilder().name(scenario.getSmFwName()).version(dsSet.getVersion()).type("os").build()) + final List modules = softwareModuleResource + .createSoftwareModules(new SoftwareModuleBuilder().name(scenario.getSmFwName() + "-os") + .version(dsSet.getVersion()).type("os").build()) .getBody(); - modules.addAll(softwareModuleResource - .createSoftwareModules( - new SoftwareModuleBuilder().name(scenario.getSmSwName()).version(dsSet.getVersion() + ".") - .type("application").buildAsList(scenario.getAppModulesPerDistributionSet())) + modules.addAll(softwareModuleResource.createSoftwareModules( + new SoftwareModuleBuilder().name(scenario.getSmSwName() + "-app").version(dsSet.getVersion() + ".") + .type("application").buildAsList(scenario.getAppModulesPerDistributionSet())) .getBody()); for (int x = 0; x < scenario.getArtifactsPerSM(); x++) { diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java index fdf5462da..00424c5e5 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java @@ -1,5 +1,10 @@ /** - * Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved. + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html */ package org.eclipse.hawkbit.mgmt.client.scenarios.upload; @@ -100,16 +105,16 @@ public class FeignMultipartEncoder implements Encoder { } } - private boolean isMultipartFile(final Object object) { + private static boolean isMultipartFile(final Object object) { return object instanceof MultipartFile; } - private class HttpOutputMessageImpl implements HttpOutputMessage { + private static final class HttpOutputMessageImpl implements HttpOutputMessage { private final OutputStream body; private final HttpHeaders headers; - public HttpOutputMessageImpl(final OutputStream body, final HttpHeaders headers) { + private HttpOutputMessageImpl(final OutputStream body, final HttpHeaders headers) { this.body = body; this.headers = headers; } diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties index e19b83e19..ac3f240a3 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties @@ -13,8 +13,10 @@ hawkbit.password=admin spring.main.show-banner=false +hawkbit.scenarios.[0].cleanRepository=true hawkbit.scenarios.[0].targets=0 hawkbit.scenarios.[0].ds-name=gettingstarted-example hawkbit.scenarios.[0].distribution-sets=3 hawkbit.scenarios.[0].sm-fw-name=gettingstarted-example -hawkbit.scenarios.[0].sm-sw-name=gettingstarted-example \ No newline at end of file +hawkbit.scenarios.[0].sm-sw-name=gettingstarted-example +hawkbit.scenarios.[0].runRollouts=false \ No newline at end of file diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/resources/logback-spring.xml b/examples/hawkbit-example-mgmt-simulator/src/main/resources/logback.xml similarity index 57% rename from examples/hawkbit-example-mgmt-simulator/src/main/resources/logback-spring.xml rename to examples/hawkbit-example-mgmt-simulator/src/main/resources/logback.xml index 0174611e6..768f30687 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/resources/logback-spring.xml +++ b/examples/hawkbit-example-mgmt-simulator/src/main/resources/logback.xml @@ -10,17 +10,11 @@ --> - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - + - + - + diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java index aa9ff3409..eabd2b329 100644 --- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java +++ b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStore.java @@ -87,9 +87,7 @@ public class ArtifactStore implements ArtifactRepository { /** * Retrieves a {@link GridFSDBFile} from the store by it's MD5 hash. - * - * @param tenant - * the tenant to retrieve the artifacts from, ignore case. + * * @param md5Hash * the md5-hash of the file to lookup. * @return The gridfs file object or {@code null} if no file exists. @@ -100,9 +98,7 @@ public class ArtifactStore implements ArtifactRepository { /** * Retrieves a {@link GridFSDBFile} from the store by it's object id. - * - * @param tenant - * the tenant to retrieve the artifacts from, ignore case. + * * @param id * the id of the file to lookup. * @return The gridfs file object or {@code null} if no file exists. @@ -231,15 +227,13 @@ public class ArtifactStore implements ArtifactRepository { * @return a paged list of artifacts mapped from the given dbFiles */ private List map(final List dbFiles) { - return dbFiles.stream().map(dbFile -> map(dbFile)).collect(Collectors.toList()); + return dbFiles.stream().map(this::map).collect(Collectors.toList()); } /** * Retrieves a list of {@link GridFSDBFile} from the store by all SHA1 * hashes. - * - * @param tenant - * the tenant to retrieve the artifacts from, ignore case. + * * @param sha1Hashes * the sha1-hashes of the files to lookup. * @return list of artifacts @@ -252,8 +246,6 @@ public class ArtifactStore implements ArtifactRepository { /** * Retrieves a list of {@link GridFSDBFile} from the store by all ids. * - * @param tenant - * the tenant to retrieve the artifacts from, ignore case. * @param ids * the ids of the files to lookup. * @return list of artfiacts diff --git a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreAutoConfiguration.java b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreAutoConfiguration.java index 43bcddaf0..8a1cb89a9 100644 --- a/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreAutoConfiguration.java +++ b/hawkbit-artifact-repository-mongo/src/main/java/org/eclipse/hawkbit/artifact/repository/ArtifactStoreAutoConfiguration.java @@ -10,18 +10,13 @@ package org.eclipse.hawkbit.artifact.repository; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; /** * Auto configuration for the {@link ArtifactStore}. - * - * - * */ @Configuration -@ComponentScan @ConditionalOnMissingBean(value = ArtifactRepository.class) @Import(value = MongoConfiguration.class) public class ArtifactStoreAutoConfiguration { From f40fbef4990dd1d0a0d2a13690e02783e26bc074 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 20 Jun 2016 08:24:28 +0200 Subject: [PATCH 23/82] Insert seleniumTest for ColorPickerLayout Signed-off-by: Melanie Retter --- .../eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java | 2 ++ .../eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java index 7d2046bd9..732523560 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java @@ -13,6 +13,7 @@ import java.util.Set; import org.eclipse.hawkbit.ui.common.CoordinatesToColor; import org.eclipse.hawkbit.ui.management.tag.SpColorPickerPreview; +import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.AbstractColorPicker.Coordinates2Color; @@ -47,6 +48,7 @@ public class ColorPickerLayout extends GridLayout { setColumns(2); setRows(4); + setId(SPUIComponentIdProvider.COLOR_PICKER_LAYOUT); init(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index b4e89a191..9757df522 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -302,6 +302,11 @@ public final class SPUIComponentIdProvider { * tag color preview button id. */ public static final String TAG_COLOR_PREVIEW_ID = "tag.color.preview"; + + /** + * Id for ColorPickerLayout + */ + public static final String COLOR_PICKER_LAYOUT = "color.picker.layout"; /** * Confirmation dialogue OK button id. */ From fb59dca1687b4d54b1313ddebff63bb4d8de35f9 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Mon, 20 Jun 2016 08:46:50 +0200 Subject: [PATCH 24/82] Added configurable late feedback functionality, i.e. action feedback still allowed even for closed action. Signed-off-by: kaizimmerm --- .../repository/RepositoryProperties.java | 29 ++++++ .../hawkbit-repository-jpa/pom.xml | 8 ++ .../RepositoryApplicationConfiguration.java | 5 +- .../jpa/JpaControllerManagement.java | 31 +++++- .../jpa/ControllerManagementTest.java | 95 ++++++++++++++++++- 5 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java new file mode 100644 index 000000000..982003812 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java @@ -0,0 +1,29 @@ +package org.eclipse.hawkbit.repository; + +import org.eclipse.hawkbit.repository.model.ActionStatus; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for the repository. + * + */ +@ConfigurationProperties("hawkbit.server.repository") +public class RepositoryProperties { + + /** + * Set to true if the repository has to reject + * {@link ActionStatus} entries for actions that are closed. Note: if this + * is enforced you have to make sure that the feedback channel from the + * devices i in order. + */ + private boolean rejectActionStatusForClosedAction = false; + + public boolean isRejectActionStatusForClosedAction() { + return rejectActionStatusForClosedAction; + } + + public void setRejectActionStatusForClosedAction(final boolean rejectActionStatusForClosedAction) { + this.rejectActionStatusForClosedAction = rejectActionStatusForClosedAction; + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/pom.xml b/hawkbit-repository/hawkbit-repository-jpa/pom.xml index bd56e9ca5..b1d60ec08 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/pom.xml +++ b/hawkbit-repository/hawkbit-repository-jpa/pom.xml @@ -136,6 +136,14 @@ fest-assert test + + org.springframework.boot + spring-boot-starter-hornetq + + + org.springframework.boot + spring-boot-starter-hornetq + diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index 50207037a..0f1d98166 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit; import java.util.HashMap; import java.util.Map; +import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler; @@ -27,6 +28,7 @@ import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -40,7 +42,7 @@ import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; /** - * General configuration for the SP Repository. + * General configuration for hawlBit's Repository. * */ @EnableJpaRepositories(basePackages = { "org.eclipse.hawkbit.repository.jpa" }) @@ -50,6 +52,7 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess @Configuration @ComponentScan @EnableAutoConfiguration +@EnableConfigurationProperties(RepositoryProperties.class) public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { /** * @return the {@link SystemSecurityContext} singleton bean which make it diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index 77b71e661..b8922c151 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -21,6 +21,7 @@ import javax.validation.constraints.NotNull; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.RepositoryConstants; +import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; @@ -94,6 +95,9 @@ public class JpaControllerManagement implements ControllerManagement { @Autowired private HawkbitSecurityProperties securityProperties; + @Autowired + private RepositoryProperties repositoryProperties; + @Autowired private TenantConfigurationRepository tenantConfigurationRepository; @@ -251,7 +255,13 @@ public class JpaControllerManagement implements ControllerManagement { public Action addUpdateActionStatus(@NotNull final ActionStatus actionStatus) { final JpaAction action = (JpaAction) actionStatus.getAction(); - if (!action.isActive()) { + // TODO: test + // if action is already closed we accept further status updates on if + // permitted so by configuration. This is especially use full if the + // action status feedback channel order from the device cannot be + // guaranteed. However, if an action is closed we do not accept further + // close messages. + if (actionIsNotActiveButIntermediateFeedbackStillAllowed(actionStatus, action)) { LOG.debug("Update of actionStatus {} for action {} not possible since action not active anymore.", actionStatus.getId(), action.getId()); return action; @@ -259,6 +269,12 @@ public class JpaControllerManagement implements ControllerManagement { return handleAddUpdateActionStatus((JpaActionStatus) actionStatus, action); } + private boolean actionIsNotActiveButIntermediateFeedbackStillAllowed(final ActionStatus actionStatus, + final JpaAction action) { + return !action.isActive() && (repositoryProperties.isRejectActionStatusForClosedAction() + || (Status.ERROR.equals(actionStatus.getStatus()) || Status.FINISHED.equals(actionStatus.getStatus()))); + } + /** * Sets {@link TargetUpdateStatus} based on given {@link ActionStatus}. * @@ -286,8 +302,7 @@ public class JpaControllerManagement implements ControllerManagement { case CANCELED: case WARNING: case RUNNING: - DeploymentHelper.updateTargetInfo(mergedTarget, TargetUpdateStatus.PENDING, false, targetInfoRepository, - entityManager); + handleIntermediateFeedback(mergedAction, mergedTarget); break; default: break; @@ -300,6 +315,16 @@ public class JpaControllerManagement implements ControllerManagement { return actionRepository.save(mergedAction); } + private void handleIntermediateFeedback(final JpaAction mergedAction, final JpaTarget mergedTarget) { + // we change the target state only if the action is still running + // otherwise this is considered as late feedback that does not have + // an impact on the state anymore. + if (mergedAction.isActive()) { + DeploymentHelper.updateTargetInfo(mergedTarget, TargetUpdateStatus.PENDING, false, targetInfoRepository, + entityManager); + } + } + private void handleErrorOnAction(final JpaAction mergedAction, final JpaTarget mergedTarget) { mergedAction.setActive(false); mergedAction.setStatus(Status.ERROR); 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 f33c5c170..77adfa45b 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 @@ -17,6 +17,7 @@ import java.util.List; import javax.validation.ConstraintViolationException; import org.apache.commons.lang3.RandomStringUtils; +import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.model.Action; @@ -26,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; @@ -34,6 +36,8 @@ import ru.yandex.qatools.allure.annotations.Stories; @Features("Component Tests - Repository") @Stories("Controller Management") public class ControllerManagementTest extends AbstractJpaIntegrationTest { + @Autowired + private RepositoryProperties repositoryProperties; @Test @Description("Controller adds a new action status.") @@ -94,7 +98,7 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Controller trys to finish an update process after it has been finished by an error action status.") - public void tryToFinishUpdateProcessMoreThenOnce() { + public void tryToFinishUpdateProcessMoreThanOnce() { // mock final Target target = new JpaTarget("Rabbit"); @@ -120,16 +124,101 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest { assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus()) .isEqualTo(TargetUpdateStatus.ERROR); + // try with disabled late feedback + repositoryProperties.setRejectActionStatusForClosedAction(true); final ActionStatus actionStatusMessage3 = new JpaActionStatus(savedAction, Action.Status.FINISHED, System.currentTimeMillis()); actionStatusMessage3.addMessage("finish"); - controllerManagament.addUpdateActionStatus(actionStatusMessage3); + savedAction = controllerManagament.addUpdateActionStatus(actionStatusMessage3); - targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus(); + // test + assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus()) + .isEqualTo(TargetUpdateStatus.ERROR); + + // try with enabled late feedback + repositoryProperties.setRejectActionStatusForClosedAction(false); + final ActionStatus actionStatusMessage4 = new JpaActionStatus(savedAction, Action.Status.FINISHED, + System.currentTimeMillis()); + actionStatusMessage4.addMessage("finish"); + controllerManagament.addUpdateActionStatus(actionStatusMessage3); // test assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus()) .isEqualTo(TargetUpdateStatus.ERROR); } + + @Test + @Description("Controller trys to send an update feedback after it has been finished which is reject as the repository is " + + "configured to reject that.") + public void sendUpdatesForFinishUpdateProcessDropedIfDisabled() { + repositoryProperties.setRejectActionStatusForClosedAction(true); + + final Action action = prepareFinishedUpdate("Rabbit"); + + final ActionStatus actionStatusMessage1 = new JpaActionStatus(action, Action.Status.RUNNING, + System.currentTimeMillis()); + actionStatusMessage1.addMessage("got some additional feedback"); + controllerManagament.addUpdateActionStatus(actionStatusMessage1); + + // nothing changed as "feedback after close" is disabled + assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus()) + .isEqualTo(TargetUpdateStatus.IN_SYNC); + assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3); + assertThat(deploymentManagement.findActionStatusByAction(pageReq, action).getNumberOfElements()).isEqualTo(3); + } + + @Test + @Description("Controller trys to send an update feedback after it has been finished which is actepted as the repository is " + + "configured to accept them.") + public void sendUpdatesForFinishUpdateProcessAcceptedIfEnabled() { + repositoryProperties.setRejectActionStatusForClosedAction(false); + + Action action = prepareFinishedUpdate("Rabbit"); + + final ActionStatus actionStatusMessage1 = new JpaActionStatus(action, Action.Status.RUNNING, + System.currentTimeMillis()); + actionStatusMessage1.addMessage("got some additional feedback"); + action = controllerManagament.addUpdateActionStatus(actionStatusMessage1); + + // nothing changed as "feedback after close" is disabled + assertThat(targetManagement.findTargetByControllerID("Rabbit").getTargetInfo().getUpdateStatus()) + .isEqualTo(TargetUpdateStatus.IN_SYNC); + assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(4); + assertThat(deploymentManagement.findActionStatusByAction(pageReq, action).getNumberOfElements()).isEqualTo(4); + } + + private Action prepareFinishedUpdate(final String controllerId) { + // mock + final Target target = new JpaTarget(controllerId); + final DistributionSet ds = testdataFactory.createDistributionSet(""); + Target savedTarget = targetManagement.createTarget(target); + final List toAssign = new ArrayList<>(); + toAssign.add(savedTarget); + savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedEntity().iterator().next(); + Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0); + + // test and verify + final ActionStatus actionStatusMessage = new JpaActionStatus(savedAction, Action.Status.RUNNING, + System.currentTimeMillis()); + actionStatusMessage.addMessage("running"); + savedAction = controllerManagament.addUpdateActionStatus(actionStatusMessage); + assertThat(targetManagement.findTargetByControllerID(controllerId).getTargetInfo().getUpdateStatus()) + .isEqualTo(TargetUpdateStatus.PENDING); + + final ActionStatus actionStatusMessage2 = new JpaActionStatus(savedAction, Action.Status.FINISHED, + System.currentTimeMillis()); + actionStatusMessage2.addMessage("finish"); + savedAction = controllerManagament.addUpdateActionStatus(actionStatusMessage2); + + // test + assertThat(targetManagement.findTargetByControllerID(controllerId).getTargetInfo().getUpdateStatus()) + .isEqualTo(TargetUpdateStatus.IN_SYNC); + + assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3); + assertThat(deploymentManagement.findActionStatusByAction(pageReq, savedAction).getNumberOfElements()) + .isEqualTo(3); + + return savedAction; + } } From 2044695aeb75464455219d39c923c2a76956a501 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Mon, 20 Jun 2016 08:56:40 +0200 Subject: [PATCH 25/82] Fixed license header. Signed-off-by: kaizimmerm --- .../eclipse/hawkbit/repository/RepositoryProperties.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java index 982003812..c60089fb3 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java @@ -1,3 +1,11 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ package org.eclipse.hawkbit.repository; import org.eclipse.hawkbit.repository.model.ActionStatus; From dbb2e00ed86b54cf6be3ff3b82911d95abf89275 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 20 Jun 2016 10:16:15 +0200 Subject: [PATCH 26/82] re-order tenant lazy initialization filter after authentication chain Signed-off-by: Michael Hirsch --- .../autoconfigure/security/SecurityManagedConfiguration.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index fc7a0a1e4..0b68246ff 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -83,6 +83,7 @@ import org.springframework.security.web.header.writers.frameoptions.StaticAllowF import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter; import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter.XFrameOptionsMode; import org.springframework.security.web.session.HttpSessionEventPublisher; +import org.springframework.security.web.session.SessionManagementFilter; import org.vaadin.spring.security.VaadinSecurityContext; import org.vaadin.spring.security.annotation.EnableVaadinSecurity; import org.vaadin.spring.security.web.VaadinDefaultRedirectStrategy; @@ -333,7 +334,7 @@ public class SecurityManagedConfiguration { }, RequestHeaderAuthenticationFilter.class) .addFilterAfter( new AuthenticationSuccessTenantMetadataCreationFilter(tenantAware, systemManagement), - RequestHeaderAuthenticationFilter.class) + SessionManagementFilter.class) .authorizeRequests().anyRequest().authenticated() .antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**") .hasAnyAuthority(SpPermission.SYSTEM_ADMIN) From deb1dde32646a7a5266e658642f6ccff57d4ec7e Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 21 Jun 2016 09:45:28 +0200 Subject: [PATCH 27/82] Add select all for mac osx Signed-off-by: SirWayne --- .../smtable/SoftwareModuleTableLayout.java | 5 -- .../ui/common/table/AbstractTableLayout.java | 85 +++++++++++-------- .../dstable/DistributionSetTableLayout.java | 5 -- .../smtable/SwModuleTableLayout.java | 6 -- .../dstable/DistributionTableLayout.java | 5 -- 5 files changed, 51 insertions(+), 55 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java index 2672c4546..421fbc89c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTableLayout.java @@ -42,9 +42,4 @@ public class SoftwareModuleTableLayout extends AbstractTableLayout { super.init(smTableHeader, smTable, softwareModuleDetails); } - @Override - protected void publishEvent() { - // nothing to publish - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java index 98874626d..905c5917c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java @@ -9,11 +9,12 @@ package org.eclipse.hawkbit.ui.common.table; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractTableDetailsLayout; -import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; import com.vaadin.event.ShortcutAction; +import com.vaadin.server.Page; +import com.vaadin.server.WebBrowser; import com.vaadin.ui.Alignment; import com.vaadin.ui.Panel; import com.vaadin.ui.VerticalLayout; @@ -24,22 +25,16 @@ import com.vaadin.ui.themes.ValoTheme; */ public abstract class AbstractTableLayout extends VerticalLayout { - private static final long serialVersionUID = 8611248179949245460L; - - /** - * action for the shortcut key ctrl + 'A'. - */ - protected static final ShortcutAction ACTION_CTRL_A = new ShortcutAction("Select All", ShortcutAction.KeyCode.A, - new int[] { ShortcutAction.ModifierKey.CTRL }); + private static final long serialVersionUID = 1L; private AbstractTableHeader tableHeader; - private AbstractTable table; + private AbstractTable table; - private AbstractTableDetailsLayout detailsLayout; + private AbstractTableDetailsLayout detailsLayout; - protected void init(final AbstractTableHeader tableHeader, final AbstractTable table, - final AbstractTableDetailsLayout detailsLayout) { + protected void init(final AbstractTableHeader tableHeader, final AbstractTable table, + final AbstractTableDetailsLayout detailsLayout) { this.tableHeader = tableHeader; this.table = table; this.detailsLayout = detailsLayout; @@ -63,24 +58,24 @@ public abstract class AbstractTableLayout extends VerticalLayout { if (isShortCutKeysRequired()) { final Panel tablePanel = new Panel(); tablePanel.setStyleName("table-panel"); - tablePanel.setHeight(100.0f, Unit.PERCENTAGE); + tablePanel.setHeight(100.0F, Unit.PERCENTAGE); tablePanel.setContent(table); tablePanel.addActionHandler(getShortCutKeysHandler()); tablePanel.addStyleName(ValoTheme.PANEL_BORDERLESS); tableHeaderLayout.addComponent(tablePanel); tableHeaderLayout.setComponentAlignment(tablePanel, Alignment.TOP_CENTER); - tableHeaderLayout.setExpandRatio(tablePanel, 1.0f); + tableHeaderLayout.setExpandRatio(tablePanel, 1.0F); } else { tableHeaderLayout.addComponent(table); tableHeaderLayout.setComponentAlignment(table, Alignment.TOP_CENTER); - tableHeaderLayout.setExpandRatio(table, 1.0f); + tableHeaderLayout.setExpandRatio(table, 1.0F); } addComponent(tableHeaderLayout); addComponent(detailsLayout); setComponentAlignment(tableHeaderLayout, Alignment.TOP_CENTER); setComponentAlignment(detailsLayout, Alignment.TOP_CENTER); - setExpandRatio(tableHeaderLayout, 1.0f); + setExpandRatio(tableHeaderLayout, 1.0F); } /** @@ -99,29 +94,51 @@ public abstract class AbstractTableLayout extends VerticalLayout { * Default is null. */ protected Handler getShortCutKeysHandler() { - return new Handler() { - - private static final long serialVersionUID = 1L; - - @Override - public void handleAction(final Action action, final Object sender, final Object target) { - if (ACTION_CTRL_A.equals(action)) { - table.selectAll(); - publishEvent(); - } - } - - @Override - public Action[] getActions(final Object target, final Object sender) { - return new Action[] { ACTION_CTRL_A }; - } - }; + return new TableShortCutHandler(); } - protected abstract void publishEvent(); + protected void publishEvent() { + // can be override by subclasses + } public void setShowFilterButtonVisible(final boolean visible) { tableHeader.setFilterButtonsIconVisible(visible); } + private class TableShortCutHandler implements Handler { + + private static final String SELECT_ALL_TEXT = "Select All"; + private final ShortcutAction selectAllAction = new ShortcutAction(SELECT_ALL_TEXT, ShortcutAction.KeyCode.A, + new int[] { ShortcutAction.ModifierKey.CTRL }); + + private final ShortcutAction selectAllMacAction = new ShortcutAction(SELECT_ALL_TEXT, ShortcutAction.KeyCode.A, + new int[] { ShortcutAction.ModifierKey.META }); + + private static final long serialVersionUID = 1L; + + @Override + public void handleAction(final Action action, final Object sender, final Object target) { + if (!isSelecAllAction(action)) { + return; + } + table.selectAll(); + publishEvent(); + } + + private boolean isSelecAllAction(final Action action) { + return selectAllAction.equals(action) || selectAllMacAction.equals(action); + } + + @Override + public Action[] getActions(final Object target, final Object sender) { + + final WebBrowser webBrowser = Page.getCurrent().getWebBrowser(); + if (webBrowser.isMacOSX()) { + return new Action[] { selectAllMacAction }; + } + + return new Action[] { selectAllAction }; + } + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java index 66c8aff0e..e15189f6a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableLayout.java @@ -46,9 +46,4 @@ public class DistributionSetTableLayout extends AbstractTableLayout { super.init(dsTableHeader, dsTable, distributionDetails); } - @Override - protected void publishEvent() { - // nothing to publish - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java index e0d4b8ac6..9d298207a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleTableLayout.java @@ -41,10 +41,4 @@ public class SwModuleTableLayout extends AbstractTableLayout { void init() { super.init(swModuleTableHeader, swModuleTable, swModuleDetails); } - - @Override - protected void publishEvent() { - // nothing to publish - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java index fefbca972..0d9a782a1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableLayout.java @@ -42,9 +42,4 @@ public class DistributionTableLayout extends AbstractTableLayout { super.init(dsTableHeader, dsTable, distributionDetails); } - @Override - protected void publishEvent() { - // nothing to publish - } - } From 437b77a1a8002e5204ceac8a992ea23eab70d758 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Tue, 21 Jun 2016 11:00:58 +0200 Subject: [PATCH 28/82] Completed configurable demo generator. Signed-off-by: kaizimmerm --- .../hawkbit/mgmt/client/Application.java | 13 +++++-- .../scenarios/ConfigurableScenario.java | 34 +++++++++++-------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java index 8ebd8830a..ac65455b5 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java @@ -10,12 +10,16 @@ package org.eclipse.hawkbit.mgmt.client; import org.eclipse.hawkbit.feign.core.client.FeignClientConfiguration; import org.eclipse.hawkbit.feign.core.client.IgnoreMultipleConsumersProducersSpringMvcContract; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtRolloutClientResource; import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; +import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource; import org.eclipse.hawkbit.mgmt.client.scenarios.ConfigurableScenario; import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample; import org.eclipse.hawkbit.mgmt.client.scenarios.upload.FeignMultipartEncoder; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -75,8 +79,13 @@ public class Application implements CommandLineRunner { } @Bean - public ConfigurableScenario configurableScenario() { - return new ConfigurableScenario(); + public ConfigurableScenario configurableScenario(final MgmtDistributionSetClientResource distributionSetResource, + @Qualifier("mgmtSoftwareModuleClientResource") final MgmtSoftwareModuleClientResource softwareModuleResource, + @Qualifier("uploadSoftwareModule") final MgmtSoftwareModuleClientResource uploadSoftwareModule, + final MgmtTargetClientResource targetResource, final MgmtRolloutClientResource rolloutResource, + final ClientConfigurationProperties clientConfigurationProperties) { + return new ConfigurableScenario(distributionSetResource, softwareModuleResource, uploadSoftwareModule, + targetResource, rolloutResource, clientConfigurationProperties); } @Bean diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java index 240f94568..33afefa26 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java @@ -31,7 +31,6 @@ import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule; import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; /** @@ -43,25 +42,30 @@ public class ConfigurableScenario { private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurableScenario.class); - @Autowired - private MgmtDistributionSetClientResource distributionSetResource; + private final MgmtDistributionSetClientResource distributionSetResource; - @Autowired - @Qualifier("mgmtSoftwareModuleClientResource") - private MgmtSoftwareModuleClientResource softwareModuleResource; + private final MgmtSoftwareModuleClientResource softwareModuleResource; - @Autowired - @Qualifier("uploadSoftwareModule") - private MgmtSoftwareModuleClientResource uploadSoftwareModule; + private final MgmtSoftwareModuleClientResource uploadSoftwareModule; - @Autowired - private MgmtTargetClientResource targetResource; + private final MgmtTargetClientResource targetResource; - @Autowired - private MgmtRolloutClientResource rolloutResource; + private final MgmtRolloutClientResource rolloutResource; - @Autowired - private ClientConfigurationProperties clientConfigurationProperties; + private final ClientConfigurationProperties clientConfigurationProperties; + + public ConfigurableScenario(final MgmtDistributionSetClientResource distributionSetResource, + @Qualifier("mgmtSoftwareModuleClientResource") final MgmtSoftwareModuleClientResource softwareModuleResource, + @Qualifier("uploadSoftwareModule") final MgmtSoftwareModuleClientResource uploadSoftwareModule, + final MgmtTargetClientResource targetResource, final MgmtRolloutClientResource rolloutResource, + final ClientConfigurationProperties clientConfigurationProperties) { + this.distributionSetResource = distributionSetResource; + this.softwareModuleResource = softwareModuleResource; + this.uploadSoftwareModule = uploadSoftwareModule; + this.targetResource = targetResource; + this.rolloutResource = rolloutResource; + this.clientConfigurationProperties = clientConfigurationProperties; + } /** * Run the default getting started scenario. From 66360721e6e29d4ee60906b6e684993d7a2dd924 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 21 Jun 2016 11:09:54 +0200 Subject: [PATCH 29/82] CSS change Signed-off-by: Melanie Retter --- .../hawkbit/ui/common/CommonDialogWindow.java | 12 +++++++++--- .../disttype/CreateUpdateDistSetTypeLayout.java | 1 - .../TargetAddUpdateWindowLayout.java | 3 --- .../ui/utils/SPUIComponentIdProvider.java | 5 +++++ .../hawkbit/customstyles/popup-common.scss | 17 ++++++++++++++++- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 80d3de078..4388ee98a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -109,9 +109,15 @@ public class CommonDialogWindow extends Window implements Serializable { public void checkMandatoryTextField(final TextChangeEvent event, final AbstractTextField textfield) { if (StringUtils.isNotBlank(event.getText())) { - getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + if (StringUtils.isNotBlank(textfield.getCaption())) { + getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + } + getRequiredFields().put(textfield.getId(), Boolean.TRUE); } else { - getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + if (StringUtils.isNotBlank(textfield.getCaption())) { + getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + } + getRequiredFields().put(textfield.getId(), Boolean.FALSE); } checkMandatoryFields(); } @@ -189,7 +195,7 @@ public class CommonDialogWindow extends Window implements Serializable { ((AbstractOrderedLayout) content).setMargin(true); } if (content instanceof GridLayout) { - addStyleName(""); + addStyleName("marginTop"); } if (null != content) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 4d5579de0..4b97ce7dd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -113,7 +113,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); - tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 5913bc9d1..9bd3972f0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -52,9 +52,6 @@ import com.vaadin.ui.themes.ValoTheme; /** * Add and Update Target. - * - * - * */ @SpringComponent @VaadinSessionScope diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index 496bb5cb4..7a7d62b87 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -927,6 +927,11 @@ public final class SPUIComponentIdProvider { */ public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id"; + /** + * Table multiselect for selecting DistType + */ + public static final String SELECT_DIST_TYPE = "select-dist-type"; + /** * /* Private Constructor. */ diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss index 602298766..bab6e5f2a 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss @@ -54,7 +54,22 @@ } .v-gridlayout .v-gridlayout-marginTop { - padding-top: 20px !important; + margin-top: 20px !important; } + .v-slot .v-slot-marginTop { + margin-top: 20px !important; + } + + .v-gridlayout-marginTop { + margin-top: 20px !important; + } + + .v-slot-marginTop { + margin-top: 20px !important; + } + + .marginTop { + margin-top: 20px !important; + } } From dfa547d382a7713055891b1cb58d3f5249d1c323 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 21 Jun 2016 11:14:22 +0200 Subject: [PATCH 30/82] update jacoco version Signed-off-by: Michael Hirsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f50afa0ab..de7a9dd6d 100644 --- a/pom.xml +++ b/pom.xml @@ -127,7 +127,7 @@ https://projects.eclipse.org/projects/iot.hawkbit https://circleci.com/gh/eclipse/hawkbit - 0.7.6.201602180812 + 0.7.7.201606060606 1.4 From 8507626b69d60ef5ee7a8fd5b9b4460666ad85d0 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Tue, 21 Jun 2016 13:41:06 +0200 Subject: [PATCH 31/82] Delete useless css styles. Update upper/lower case in properties Signed-off-by: Melanie Retter --- .../hawkbit/customstyles/popup-common.scss | 16 ------- .../src/main/resources/messages.properties | 38 ++++++++--------- .../src/main/resources/messages_de.properties | 42 +++++++++---------- .../src/main/resources/messages_en.properties | 42 +++++++++---------- 4 files changed, 61 insertions(+), 77 deletions(-) diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss index bab6e5f2a..b8e6b1755 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/popup-common.scss @@ -53,22 +53,6 @@ font-size: 16px; } - .v-gridlayout .v-gridlayout-marginTop { - margin-top: 20px !important; - } - - .v-slot .v-slot-marginTop { - margin-top: 20px !important; - } - - .v-gridlayout-marginTop { - margin-top: 20px !important; - } - - .v-slot-marginTop { - margin-top: 20px !important; - } - .marginTop { margin-top: 20px !important; } diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 1fee8dcdb..5b3ad793b 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -79,14 +79,14 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type caption.delete.sw.module.type.accordion.tab = Delete Software Module Type caption.attributes = Attributes -caption.panel.dist.installed = Installed distribution set -caption.panel.dist.assigned = Assigned distribution set +caption.panel.dist.installed = Installed Distribution Set +caption.panel.dist.assigned = Assigned Distribution Set caption.soft.delete.confirmbox = Confirm Software Module Delete Action -caption.cancel.action.confirmbox = Confirm action cancel +caption.cancel.action.confirmbox = Confirm Action Cancellation caption.forcequit.action.confirmbox = Confirm force quit action caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action -caption.confirm.abort.action = Confirm abort action +caption.confirm.abort.action = Confirm Abort Action caption.filter.delete.confirmbox = Confirm Filter Delete Action @@ -220,7 +220,7 @@ message.duplicate.softwaremodule = {0} : {1} already exists! message.tag.delete = Please unclick the tag {0}, then try to delete message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete message.cannot.delete.default.dstype = Default distribution set type cannot be deleted -message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete +message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete message.targets.already.deleted = Few Target(s) are already deleted.Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action @@ -262,10 +262,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1} message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1} message.dist.no.operation = {0} - already assigned/installed, No operation -message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module? +message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module? message.error.os.softmodule = Please select the OS to delete message.error.ah.softmodule = Please select the Application to delete -message.error.softmodule.deleted = The selected software module is already deleted +message.error.softmodule.deleted = The selected Software Module is already deleted message.cancel.action = Cancel.. message.cancel.action.success = Action cancelled successfully ! message.cancel.action.failed = Unable to cancel the action ! @@ -284,7 +284,7 @@ message.action.not.allowed = Action not allowed message.onlyone.distribution.assigned = Only one distribution set can be assigned message.onlyone.distribution.dropallowed = Only one distribution set can be dropped message.error.missing.typename = Missing Type Name -message.error.missing.typenameorkey = Missing Type Name or Key or software module type +message.error.missing.typenameorkey = Missing Type Name or Key or Software Module type message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0} message.no.targets.assiged.fortag = No targets are assigned to tag {0} message.error.missing.tagname = Please select tag name @@ -314,12 +314,12 @@ soft.module.os =OS #Artifact upload message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name -message.error.noSwModuleSelected = Please select a software module +message.error.noSwModuleSelected = Please select a Software Module message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name -message.swModule.deleted = {0} Software module(s) deleted +message.swModule.deleted = {0} Software Module(s) deleted message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes message.uploadedfile.aborted = File upload aborted @@ -329,7 +329,7 @@ message.abort.upload = Are you sure that you want to abort the upload? -upload.swModuleTable.header = Software module +upload.swModuleTable.header = Software Module upload.selectedfile.name = file selected for upload upload.file.name = File name upload.sha1 = SHA1 checksum @@ -347,7 +347,7 @@ upload.reason = Reason upload.action = Action upload.result.status = Upload status upload.file = Upload File -upload.caption.update.swmodule = Update software module +upload.caption.update.swmodule = Update Software Module caption.tab.details = Details caption.tab.description = Description @@ -363,8 +363,8 @@ label.no.tag.assigned = NO TAG caption.assign.software.dist.accordion.tab = Assign Software Modules message.software.assignment = {0} Software Module(s) Assignment(s) done message.dist.inuse = {0} Distribution is already assigned to target -message.software.dist.already.assigned = {0} Distribution already has software module {1} -message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1} +message.software.dist.already.assigned = {0} Distribution already has Software Module {1} +message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1} message.target.assigned = {0} is assigned to {1} message.dist.type.delete = {0} DistributionType(s) Deleted successfully. message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully. @@ -445,7 +445,7 @@ header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType header.caption.softwaremodule = SoftwareModule header.caption.unassign = Unassign -message.sw.unassigned = Software module {0} successfully unassigned +message.sw.unassigned = Software Module {0} successfully unassigned header.caption.upload.details = Upload details combo.type.tag.name = Type tag name @@ -469,8 +469,8 @@ prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold prompt.distribution.set = Distribution set -caption.configure.rollout = Configure rollout -caption.update.rollout = Update rollout +caption.configure.rollout = Configure Rollout +caption.update.rollout = Update Rollout prompt.target.filter = Custom target filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 @@ -485,8 +485,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou message.rollouts = Rollouts label.target.per.group = Targets per group : message.dist.already.assigned = Distribution {0} is already assigned to target -message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator -message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator +message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator +message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator #rollout - end #Menu diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index 1c437071a..2ac5ed9c2 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -77,16 +77,16 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type caption.delete.sw.module.type.accordion.tab = Delete Software Module Type caption.attributes = Attributes -caption.panel.dist.installed = Installed distribution set -caption.panel.dist.assigned = Assigned distribution set +caption.panel.dist.installed = Installed Distribution Set +caption.panel.dist.assigned = Assigned Distribution Set caption.soft.delete.confirmbox = Confirm Software Module Delete Action -caption.cancel.action.confirmbox = Confirm action cancellation +caption.cancel.action.confirmbox = Confirm Action Cancellation caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action caption.filter.simple = Simple Filter caption.filter.custom = Custom Filter caption.filter.delete.confirmbox = Confirm Filter Delete Action -caption.confirm.abort.action = Confirm abort action +caption.confirm.abort.action = Confirm Abort Action # Labels prefix with - label @@ -214,13 +214,13 @@ message.target.unassigned.one = {0} is unassigned from {1} message.target.unassigned.many = {0} Targets are unassigned from {1} message.target.assigned.pending = Some target(s) are already assigned.Pending for action message.cannot.delete = Cannot be deleted -message.check.softwaremodule = Please provide both name and verion! +message.check.softwaremodule = Please provide both name and version! message.cannot.delete.default.dstype = Default distribution set type cannot be deleted message.duplicate.softwaremodule = {0} : {1} already exists! message.cannot.delete.default.dstype = Default distribution set type cannot be deleted message.tag.delete = Please unclick the tag {0}, then try to delete message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete -message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete +message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete message.targets.already.deleted = Few Target(s) are already deleted.Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action @@ -243,7 +243,7 @@ message.accessdenied.view = No access to view: {0} message.no.data = No data available message.target.assignment = {0} Assignment(s) done message.target.deleted = {0} Target(s) deleted -message.dist.deleted = {0} Distribution set(s) deleted +message.dist.deleted = {0} Distribution Set(s) deleted message.tag.update.mandatory = Please select the Tag to update message.tag.duplicate.check = {0} already exists, please enter another value message.type.key.duplicate.check = Distribution type with key {0} already exists, please give another value @@ -262,10 +262,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1} message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1} message.dist.no.operation = {0} - already assigned/installed, No operation -message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module? +message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module? message.error.os.softmodule = Please select the OS to delete message.error.ah.softmodule = Please select the Application to delete -message.error.softmodule.deleted = The selected software module is already deleted +message.error.softmodule.deleted = The selected Software Module is already deleted message.cancel.action = Cancel message.cancel.action.success = Action cancelled successfully ! message.cancel.action.failed = Unable to cancel the action ! @@ -311,12 +311,12 @@ soft.module.os =OS #Artifact upload message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name -message.error.noSwModuleSelected = Please select a software module +message.error.noSwModuleSelected = Please select a Software Module message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name -message.swModule.deleted = {0} Software module(s) deleted +message.swModule.deleted = {0} Software Module(s) deleted message.error.missing.tagname = Please select tag name message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes @@ -327,7 +327,7 @@ message.abort.upload = Are you sure that you want to abort the upload? -upload.swModuleTable.header = Software module +upload.swModuleTable.header = Software Module upload.selectedfile.name = file selected for upload upload.file.name = File name upload.sha1 = SHA1 checksum @@ -345,7 +345,7 @@ upload.reason = Reason upload.action = Action upload.result.status = Upload status upload.file = Upload File -upload.caption.update.swmodule = Update software module +upload.caption.update.swmodule = Update Software Module caption.tab.details = Details caption.tab.description = Description @@ -356,8 +356,8 @@ label.drop.dist.delete.area = Drop here
to delete caption.assign.software.dist.accordion.tab = Assign Software Modules message.software.assignment = {0} Assignment(s) done message.dist.inuse = {0} Distribution is already assigned to target -message.software.dist.already.assigned = {0} Distribution already has software module {1} -message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1} +message.software.dist.already.assigned = {0} Distribution already has Software Module {1} +message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1} message.target.assigned = {0} is assigned to {1} message.dist.type.delete = {0} DistributionType(s) Deleted successfully. message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully. @@ -442,7 +442,7 @@ header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType header.caption.softwaremodule = SoftwareModule header.caption.unassign = Unassign -message.sw.unassigned = Software module {0} successfully unassigned +message.sw.unassigned = Software Module {0} successfully unassigned header.caption.upload.details = Upload details combo.type.tag.name = Type tag name @@ -458,9 +458,9 @@ menu.title = Software Provisioning prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold -prompt.distribution.set = Distribution set -caption.configure.rollout = Configure rollout -caption.update.rollout = Update rollout +prompt.distribution.set = Distribution Set +caption.configure.rollout = Configure Rollout +caption.update.rollout = Update Rollout prompt.target.filter = Custom target filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 @@ -475,8 +475,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou message.rollouts = Rollouts label.target.per.group = Targets per group : message.dist.already.assigned = Distribution {0} is already assigned to target -message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator -message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator +message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator +message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator #Target Filter Management breadcrumb.target.filter.custom.filters = Custom Filters diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index 7716da4f2..459695844 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -79,14 +79,14 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type caption.delete.sw.module.type.accordion.tab = Delete Software Module Type caption.attributes = Attributes -caption.panel.dist.installed = Installed distribution set -caption.panel.dist.assigned = Assigned distribution set +caption.panel.dist.installed = Installed Distribution Set +caption.panel.dist.assigned = Assigned Distribution Set caption.soft.delete.confirmbox = Confirm Software Module Delete Action -caption.cancel.action.confirmbox = Confirm action cancellation +caption.cancel.action.confirmbox = Confirm Action Cancellation caption.forced.datefield = Force update at time caption.force.action.confirmbox = Confirm Force Active Action caption.filter.delete.confirmbox = Confirm Filter Delete Action -caption.confirm.abort.action = Confirm abort action +caption.confirm.abort.action = Confirm Abort Action # Labels prefix with - label label.dist.details.type = Type : @@ -213,11 +213,11 @@ message.target.unassigned.one = {0} is unassigned from {1} message.target.unassigned.many = {0} Targets are unassigned from {1} message.target.assigned.pending = Some target(s) are already assigned.Pending for action message.cannot.delete = Cannot be deleted -message.check.softwaremodule = Please provide both name and verion! +message.check.softwaremodule = Please provide both name and version! message.duplicate.softwaremodule = {0} : {1} already exists! message.tag.delete = Please unclick the tag {0}, then try to delete message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete -message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete +message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete message.targets.already.deleted = Few Target(s) are already deleted.Pending for action message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action message.target.deleted.pending = Target(s) already deleted.Pending for action @@ -259,10 +259,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1} message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1} message.dist.no.operation = {0} - already assigned/installed, No operation -message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module? +message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module? message.error.os.softmodule = Please select the OS to delete message.error.ah.softmodule = Please select the Application to delete -message.error.softmodule.deleted = The selected software module is already deleted +message.error.softmodule.deleted = The selected Software Module is already deleted message.cancel.action = Cancel message.cancel.action.success = Action cancelled successfully ! message.cancel.action.failed = Unable to cancel the action ! @@ -277,7 +277,7 @@ message.action.not.allowed = Action not allowed message.onlyone.distribution.assigned = Only one distribution set can be assigned message.onlyone.distribution.dropallowed = Only one distribution set can be dropped message.error.missing.typename = Missing Type Name -message.error.missing.typenameorkey = Missing Type Name or Key or software module type +message.error.missing.typenameorkey = Missing Type Name or Key or Software Module type message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0} message.no.targets.assiged.fortag = No targets are assigned to tag {0} message.error.missing.tagname = Please select tag name @@ -305,12 +305,12 @@ soft.module.os =OS #Artifact upload message.error.noFileSelected = No file selected for upload message.error.noProvidedName = Please provide custom file name -message.error.noSwModuleSelected = Please select a software module +message.error.noSwModuleSelected = Please select a Software Module message.no.duplicateFiles = Duplicate files selected message.no.duplicateFile = Duplicate file selected : message.delete.artifact = Are you sure that you want to delete artifact {0} ? message.duplicate.filename = Duplicate file name -message.swModule.deleted = {0} Software module(s) deleted +message.swModule.deleted = {0} Software Module(s) deleted message.upload.failed = Streaming Failed message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes message.uploadedfile.aborted = File upload aborted @@ -318,7 +318,7 @@ message.file.not.found = File not found message.abort.upload = Are you sure that you want to abort the upload? -upload.swModuleTable.header = Software module +upload.swModuleTable.header = Software Module upload.selectedfile.name = file selected for upload upload.file.name = File name upload.sha1 = SHA1 checksum @@ -336,7 +336,7 @@ upload.reason = Reason upload.action = Action upload.result.status = Upload status upload.file = Upload File -upload.caption.update.swmodule = Update software module +upload.caption.update.swmodule = Update Software Module caption.tab.details = Details caption.tab.description = Description @@ -348,8 +348,8 @@ label.drop.dist.delete.area = Drop here
to delete caption.assign.software.dist.accordion.tab = Assign Software Modules message.software.assignment = {0} Software Module(s) Assignment(s) done message.dist.inuse = {0} Distribution is already assigned to target -message.software.dist.already.assigned = {0} Distribution already has software module {1} -message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1} +message.software.dist.already.assigned = {0} Distribution already has Software Module {1} +message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1} message.target.assigned = {0} is assigned to {1} message.dist.type.delete = {0} DistributionType(s) Deleted successfully. message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully. @@ -415,7 +415,7 @@ header.assigned.ds = Assigned DS header.installed.ds = Installed DS header.status = Status header.target.tags = Tags -header.distributionset = Distribution set +header.distributionset = Distribution Set header.numberofgroups = No. of groups header.detail.status = Detail status header.total.targets = Total targets @@ -429,7 +429,7 @@ header.rolloutgroup.target.message = Messages rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1} -distribution.details.header = Distribution set +distribution.details.header = Distribution Set target.details.header = Target header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType @@ -449,8 +449,8 @@ prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold prompt.distribution.set = Distribution set -caption.configure.rollout = Configure rollout -caption.update.rollout = Update rollout +caption.configure.rollout = Configure Rollout +caption.update.rollout = Update Rollout prompt.target.filter = Custom target filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 @@ -465,8 +465,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou message.rollouts = Rollouts label.target.per.group = Targets per group : message.dist.already.assigned = Distribution {0} is already assigned to target -message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator -message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator +message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator +message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator #Target Filter Management breadcrumb.target.filter.custom.filters = Custom Filters From b7ea17498367d6727cd7149534ecca6f5156662e Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 21 Jun 2016 13:42:26 +0200 Subject: [PATCH 32/82] Add a shortcut modifier util class to handle cross platform functionality. Signed-off-by: SirWayne --- .../ui/common/table/AbstractTableLayout.java | 20 ++------- .../ui/utils/ShortCutModifierUtils.java | 41 +++++++++++++++++++ 2 files changed, 44 insertions(+), 17 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/ShortCutModifierUtils.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java index 905c5917c..11c0083ec 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableLayout.java @@ -9,12 +9,11 @@ package org.eclipse.hawkbit.ui.common.table; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractTableDetailsLayout; +import org.eclipse.hawkbit.ui.utils.ShortCutModifierUtils; import com.vaadin.event.Action; import com.vaadin.event.Action.Handler; import com.vaadin.event.ShortcutAction; -import com.vaadin.server.Page; -import com.vaadin.server.WebBrowser; import com.vaadin.ui.Alignment; import com.vaadin.ui.Panel; import com.vaadin.ui.VerticalLayout; @@ -109,34 +108,21 @@ public abstract class AbstractTableLayout extends VerticalLayout { private static final String SELECT_ALL_TEXT = "Select All"; private final ShortcutAction selectAllAction = new ShortcutAction(SELECT_ALL_TEXT, ShortcutAction.KeyCode.A, - new int[] { ShortcutAction.ModifierKey.CTRL }); - - private final ShortcutAction selectAllMacAction = new ShortcutAction(SELECT_ALL_TEXT, ShortcutAction.KeyCode.A, - new int[] { ShortcutAction.ModifierKey.META }); + new int[] { ShortCutModifierUtils.getCtrlOrMetaModifier() }); private static final long serialVersionUID = 1L; @Override public void handleAction(final Action action, final Object sender, final Object target) { - if (!isSelecAllAction(action)) { + if (!selectAllAction.equals(action)) { return; } table.selectAll(); publishEvent(); } - private boolean isSelecAllAction(final Action action) { - return selectAllAction.equals(action) || selectAllMacAction.equals(action); - } - @Override public Action[] getActions(final Object target, final Object sender) { - - final WebBrowser webBrowser = Page.getCurrent().getWebBrowser(); - if (webBrowser.isMacOSX()) { - return new Action[] { selectAllMacAction }; - } - return new Action[] { selectAllAction }; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/ShortCutModifierUtils.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/ShortCutModifierUtils.java new file mode 100644 index 000000000..b844caafd --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/ShortCutModifierUtils.java @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.ui.utils; + +import com.vaadin.event.ShortcutAction; +import com.vaadin.server.Page; +import com.vaadin.server.WebBrowser; + +/** + * On different systems there are different modifier for short cuts. This + * utility class handles the cross-platform functionality. + */ +public final class ShortCutModifierUtils { + + private ShortCutModifierUtils() { + + } + + /** + * Returns the ctrl or meta modifier depending on the platform. + * + * @return on mac return + * {@link com.vaadin.event.ShortcutAction.ModifierKey#META} other + * platform return + * {@link com.vaadin.event.ShortcutAction.ModifierKey#CTRL} + */ + public static int getCtrlOrMetaModifier() { + final WebBrowser webBrowser = Page.getCurrent().getWebBrowser(); + if (webBrowser.isMacOSX()) { + return ShortcutAction.ModifierKey.META; + } + + return ShortcutAction.ModifierKey.CTRL; + } +} From 6f5f2e798ba5c376799bb4481b37eba125f59af5 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 21 Jun 2016 15:19:26 +0200 Subject: [PATCH 33/82] add javdoc Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/simulator/AbstractSimulatedDevice.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java index c70d4f584..a2a036e1b 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/AbstractSimulatedDevice.java @@ -96,7 +96,11 @@ public abstract class AbstractSimulatedDevice { this.pollDelaySec = pollDelaySec; } - abstract public void poll(); + /** + * Can be called by a scheduler to trigger a device polling, like in real + * scenarios devices are frequently asking for updates etc. + */ + public abstract void poll(); public int getPollDelaySec() { return pollDelaySec; From a75a022ca611f63993f98b3ad61a8839904d365a Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 21 Jun 2016 15:19:45 +0200 Subject: [PATCH 34/82] make poll-time in dialog always visible Signed-off-by: Michael Hirsch --- .../java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java index e337e86e7..272531407 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java @@ -76,7 +76,6 @@ public class GenerateDialog extends Window { pollDelayTextField = createRequiredTextfield("poll delay (sec)", new ObjectProperty(10), FontAwesome.CLOCK_O, new RangeValidator("Must be between 1 and 60", Integer.class, 1, 60)); - pollDelayTextField.setVisible(false); pollUrlTextField = createRequiredTextfield("base poll URL endpoint", "http://localhost:8080", FontAwesome.FLAG_O, new RegexpValidator( @@ -193,7 +192,6 @@ public class GenerateDialog extends Window { protocolGroup.select(Protocol.DMF_AMQP); protocolGroup.addValueChangeListener(event -> { final boolean directDeviceOptionSelected = event.getProperty().getValue().equals(Protocol.DDI_HTTP); - pollDelayTextField.setVisible(directDeviceOptionSelected); pollUrlTextField.setVisible(directDeviceOptionSelected); gatewayTokenTextField.setVisible(directDeviceOptionSelected); }); From 95ce14ffb4be218c386a6eda566a66bba5005b70 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 21 Jun 2016 15:36:53 +0200 Subject: [PATCH 35/82] write javadoc Signed-off-by: Michael Hirsch --- .../hawkbit/mgmt/client/scenarios/ConfigurableScenario.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java index 33afefa26..2cb339a1f 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java @@ -35,7 +35,9 @@ import org.springframework.beans.factory.annotation.Qualifier; /** * - * Default getting started scenario. + * A configurable scenario which runs the configured scenarios. + * + * @see {@link ClientConfigurationProperties#getScenarios()} * */ public class ConfigurableScenario { From 2e23ed3871ebec786826ab1a7091e15e75ddc21f Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 21 Jun 2016 15:37:22 +0200 Subject: [PATCH 36/82] remove scala dependency Signed-off-by: Michael Hirsch --- hawkbit-dmf-amqp/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hawkbit-dmf-amqp/pom.xml b/hawkbit-dmf-amqp/pom.xml index 322dd5047..289d97663 100644 --- a/hawkbit-dmf-amqp/pom.xml +++ b/hawkbit-dmf-amqp/pom.xml @@ -159,11 +159,6 @@ spring-context-support test - - org.scala-lang - scala-library - 2.10.4 - \ No newline at end of file From bf1ca010c7c9634e69ae8b62bfb52589da485801 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 21 Jun 2016 16:36:01 +0200 Subject: [PATCH 37/82] throw correct exception if target address violates rfc standard Signed-off-by: Michael Hirsch --- .../hawkbit/exception/SpServerError.java | 86 +++++++------------ .../InvalidTargetAddressException.java | 42 +++++++++ .../repository/jpa/model/JpaTargetInfo.java | 9 +- .../exception/ResponseExceptionHandler.java | 1 + 4 files changed, 83 insertions(+), 55 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java index 003b31cd7..7d618e234 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java @@ -24,82 +24,73 @@ public enum SpServerError { /** * */ - SP_REPO_ENTITY_ALRREADY_EXISTS("hawkbit.server.error.repo.entitiyAlreayExists", - "The given entity already exists in database"), + SP_REPO_ENTITY_ALRREADY_EXISTS("hawkbit.server.error.repo.entitiyAlreayExists", "The given entity already exists in database"), + + /** + * + */ + SP_REPO_INVALID_TARGET_ADDRESS("hawkbit.server.error.repo.invalidTargetAddress", "The target address is not well formed"), /** * */ - SP_REPO_ENTITY_NOT_EXISTS("hawkbit.server.error.repo.entitiyNotFound", - "The given entity does not exist in database"), + SP_REPO_ENTITY_NOT_EXISTS("hawkbit.server.error.repo.entitiyNotFound", "The given entity does not exist in database"), /** * */ - SP_REPO_CONCURRENT_MODIFICATION("hawkbit.server.error.repo.concurrentModification", - "The given entity has been changed by another user/session"), + SP_REPO_CONCURRENT_MODIFICATION("hawkbit.server.error.repo.concurrentModification", "The given entity has been changed by another user/session"), /** * */ - SP_REST_SORT_PARAM_SYNTAX("hawkbit.server.error.rest.param.sortParamSyntax", - "The given sort paramter is not well formed"), + SP_REST_SORT_PARAM_SYNTAX("hawkbit.server.error.rest.param.sortParamSyntax", "The given sort paramter is not well formed"), /** * */ - SP_REST_RSQL_SEARCH_PARAM_SYNTAX("hawkbit.server.error.rest.param.rsqlParamSyntax", - "The given search paramter is not well formed"), + SP_REST_RSQL_SEARCH_PARAM_SYNTAX("hawkbit.server.error.rest.param.rsqlParamSyntax", "The given search paramter is not well formed"), /** * */ - SP_REST_RSQL_PARAM_INVALID_FIELD("hawkbit.server.error.rest.param.rsqlInvalidField", - "The given search parameter field does not exist"), + SP_REST_RSQL_PARAM_INVALID_FIELD("hawkbit.server.error.rest.param.rsqlInvalidField", "The given search parameter field does not exist"), /** * */ - SP_REST_SORT_PARAM_INVALID_FIELD("hawkbit.server.error.rest.param.invalidField", - "The given sort parameter field does not exist"), + SP_REST_SORT_PARAM_INVALID_FIELD("hawkbit.server.error.rest.param.invalidField", "The given sort parameter field does not exist"), /** * */ - SP_REST_SORT_PARAM_INVALID_DIRECTION("hawkbit.server.error.rest.param.invalidDirection", - "The given sort parameter direction does not exist"), + SP_REST_SORT_PARAM_INVALID_DIRECTION("hawkbit.server.error.rest.param.invalidDirection", "The given sort parameter direction does not exist"), /** * */ - SP_REST_BODY_NOT_READABLE("hawkbit.server.error.rest.body.notReadable", - "The given request body is not well formed"), + SP_REST_BODY_NOT_READABLE("hawkbit.server.error.rest.body.notReadable", "The given request body is not well formed"), /** * */ - SP_ARTIFACT_UPLOAD_FAILED("hawkbit.server.error.artifact.uploadFailed", - "Upload of artifact failed with internal server error."), + SP_ARTIFACT_UPLOAD_FAILED("hawkbit.server.error.artifact.uploadFailed", "Upload of artifact failed with internal server error."), /** * */ - SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH("hawkbit.server.error.artifact.uploadFailed.checksum.md5.match", - "Upload of artifact failed as the provided MD5 checksum did not match with the provided artifact."), + SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH("hawkbit.server.error.artifact.uploadFailed.checksum.md5.match", "Upload of artifact failed as the provided MD5 checksum did not match with the provided artifact."), /** * */ - SP_ARTIFACT_UPLOAD_FAILED_SHA1_MATCH("hawkbit.server.error.artifact.uploadFailed.checksum.sha1.match", - "Upload of artifact failed as the provided SHA1 checksum did not match with the provided artifact."), + SP_ARTIFACT_UPLOAD_FAILED_SHA1_MATCH("hawkbit.server.error.artifact.uploadFailed.checksum.sha1.match", "Upload of artifact failed as the provided SHA1 checksum did not match with the provided artifact."), /** * */ - SP_DS_CREATION_FAILED_MISSING_MODULE("hawkbit.server.error.distributionset.creationFailed.missingModule", - "Creation if Distribution Set failed as module is missing that is configured as mandatory."), + SP_DS_CREATION_FAILED_MISSING_MODULE("hawkbit.server.error.distributionset.creationFailed.missingModule", "Creation if Distribution Set failed as module is missing that is configured as mandatory."), /** * */ - SP_ARTIFACT_UPLOAD_FILE_LIMIT_EXCEEDED("hawkbit.server.error.artifact.uploadFailed.sizelimitexceeded", - "Upload of artifact failed as the file exceeds its maximum permitted size"), + SP_ARTIFACT_UPLOAD_FILE_LIMIT_EXCEEDED("hawkbit.server.error.artifact.uploadFailed.sizelimitexceeded", "Upload of artifact failed as the file exceeds its maximum permitted size"), /** * */ @@ -108,63 +99,53 @@ public enum SpServerError { /** * */ - SP_ARTIFACT_DELETE_FAILED("hawkbit.server.error.artifact.deleteFailed", - "Deletion of artifact failed with internal server error."), + SP_ARTIFACT_DELETE_FAILED("hawkbit.server.error.artifact.deleteFailed", "Deletion of artifact failed with internal server error."), /** * */ - SP_ARTIFACT_LOAD_FAILED("hawkbit.server.error.artifact.loadFailed", - "Load of artifact failed with internal server error."), + SP_ARTIFACT_LOAD_FAILED("hawkbit.server.error.artifact.loadFailed", "Load of artifact failed with internal server error."), /** * */ - SP_ACTION_STATUS_TO_MANY_ENTRIES("hawkbit.server.error.action.status.tooManyEntries", - "Too many status entries have been inserted."), + SP_ACTION_STATUS_TO_MANY_ENTRIES("hawkbit.server.error.action.status.tooManyEntries", "Too many status entries have been inserted."), /** * */ - SP_ATTRIBUTES_TO_MANY_ENTRIES("hawkbit.server.error.target.attributes.tooManyEntries", - "Too many attribute entries have been inserted."), + SP_ATTRIBUTES_TO_MANY_ENTRIES("hawkbit.server.error.target.attributes.tooManyEntries", "Too many attribute entries have been inserted."), /** * error message, which describes that the action can not be canceled cause * the action is inactive. */ - SP_ACTION_NOT_CANCELABLE("hawkbit.server.error.action.notcancelable", - "Only active actions which are in status pending are canceable."), + SP_ACTION_NOT_CANCELABLE("hawkbit.server.error.action.notcancelable", "Only active actions which are in status pending are canceable."), /** * error message, which describes that the action can not be force quit * cause the action is inactive. */ - SP_ACTION_NOT_FORCE_QUITABLE("hawkbit.server.error.action.notforcequitable", - "Only active actions which are in status pending can be force quit."), + SP_ACTION_NOT_FORCE_QUITABLE("hawkbit.server.error.action.notforcequitable", "Only active actions which are in status pending can be force quit."), /** * */ - SP_DS_INCOMPLETE("hawkbit.server.error.distributionset.incomplete", - "Distribution set is assigned to a a target that is incomplete (i.e. mandatory modules are missing)"), + SP_DS_INCOMPLETE("hawkbit.server.error.distributionset.incomplete", "Distribution set is assigned to a a target that is incomplete (i.e. mandatory modules are missing)"), /** * */ - SP_DS_TYPE_UNDEFINED("hawkbit.server.error.distributionset.type.undefined", - "Distribution set type is not yet defined. Modules cannot be added until definition."), + SP_DS_TYPE_UNDEFINED("hawkbit.server.error.distributionset.type.undefined", "Distribution set type is not yet defined. Modules cannot be added until definition."), /** * */ - SP_DS_MODULE_UNSUPPORTED("hawkbit.server.error.distributionset.modules.unsupported", - "Distribution set type does not contain the given module, i.e. is incompatible."), + SP_DS_MODULE_UNSUPPORTED("hawkbit.server.error.distributionset.modules.unsupported", "Distribution set type does not contain the given module, i.e. is incompatible."), /** * */ - SP_REPO_TENANT_NOT_EXISTS("hawkbit.server.error.repo.tenantNotExists", - "The entity cannot be inserted due the tenant does not exists"), + SP_REPO_TENANT_NOT_EXISTS("hawkbit.server.error.repo.tenantNotExists", "The entity cannot be inserted due the tenant does not exists"), /** * @@ -174,14 +155,12 @@ public enum SpServerError { /** * */ - SP_REPO_ENTITY_READ_ONLY("hawkbit.server.error.entityreadonly", - "The given entity is read only and the change cannot be completed."), + SP_REPO_ENTITY_READ_ONLY("hawkbit.server.error.entityreadonly", "The given entity is read only and the change cannot be completed."), /** * */ - SP_CONFIGURATION_VALUE_INVALID("hawkbit.server.error.configValueInvalid", - "The given configuration value is invalid."), + SP_CONFIGURATION_VALUE_INVALID("hawkbit.server.error.configValueInvalid", "The given configuration value is invalid."), /** * */ @@ -190,8 +169,7 @@ public enum SpServerError { /** * */ - SP_ROLLOUT_ILLEGAL_STATE("hawkbit.server.error.rollout.illegalstate", - "The rollout is currently in the wrong state for the current operation"); + SP_ROLLOUT_ILLEGAL_STATE("hawkbit.server.error.rollout.illegalstate", "The rollout is currently in the wrong state for the current operation"); private final String key; private final String message; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java new file mode 100644 index 000000000..70b890483 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.exception; + +import org.eclipse.hawkbit.exception.SpServerError; +import org.eclipse.hawkbit.exception.SpServerRtException; + +/** + * Exception which is thrown when trying to set an invalid target address. + */ +public class InvalidTargetAddressException extends SpServerRtException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * @param message + * the message for this exception + */ + public InvalidTargetAddressException(final String message) { + super(message, SpServerError.SP_REPO_INVALID_TARGET_ADDRESS); + } + + /** + * + * @param message + * the message for this exception + * @param cause + * the cause for this exception + */ + public InvalidTargetAddressException(final String message, final Throwable cause) { + super(message, SpServerError.SP_REPO_INVALID_TARGET_ADDRESS, cause); + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index 15abc2d61..0606def4f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -37,6 +37,7 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Transient; +import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -173,10 +174,16 @@ public class JpaTargetInfo implements Persistable, TargetInfo { * @throws IllegalArgumentException * If the given string violates RFC 2396 */ + @Override public void setAddress(final String address) { // check if this is a real URI if (address != null) { - URI.create(address); + try { + URI.create(address); + } catch (final IllegalArgumentException e) { + throw new InvalidTargetAddressException( + "The given address " + address + " violates the RFC-2396 specification", e); + } } this.address = address; diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java index 0f8da9ebe..31e4a3046 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java @@ -67,6 +67,7 @@ public class ResponseExceptionHandler { ERROR_TO_HTTP_STATUS.put(SpServerError.SP_ROLLOUT_ILLEGAL_STATE, HttpStatus.BAD_REQUEST); ERROR_TO_HTTP_STATUS.put(SpServerError.SP_CONFIGURATION_VALUE_INVALID, HttpStatus.BAD_REQUEST); ERROR_TO_HTTP_STATUS.put(SpServerError.SP_CONFIGURATION_KEY_INVALID, HttpStatus.BAD_REQUEST); + ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_INVALID_TARGET_ADDRESS, HttpStatus.BAD_REQUEST); } private static HttpStatus getStatusOrDefault(final SpServerError error) { From 7cb3b2f2ff45952ac5656dce704498be5e266151 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Tue, 21 Jun 2016 18:05:20 +0200 Subject: [PATCH 38/82] Added storage of clients correlation ID in action history. Signed-off-by: kaizimmerm --- .../eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 7 +++++++ .../hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index caa11ab3d..73f9e14df 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -35,6 +35,7 @@ import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.EntityFactory; +import org.eclipse.hawkbit.repository.RepositoryConstants; import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.TenantNotExistException; @@ -69,6 +70,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.web.util.UriComponentsBuilder; +import com.google.common.base.Strings; import com.google.common.eventbus.EventBus; /** @@ -346,6 +348,11 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final ActionStatus actionStatus = entityFactory.generateActionStatus(); actionUpdateStatus.getMessage().forEach(actionStatus::addMessage); + if (!Strings.isNullOrEmpty(message.getMessageProperties().getCorrelationIdString())) { + actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " + + message.getMessageProperties().getCorrelationIdString()); + } + actionStatus.setAction(action); actionStatus.setOccurredAt(System.currentTimeMillis()); diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java index e93e1340f..8cd92d2bd 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java @@ -33,7 +33,6 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("Test to generate the artifact download URL") @SpringApplicationConfiguration(classes = { AmqpTestConfiguration.class, org.eclipse.hawkbit.RepositoryApplicationConfiguration.class }) - public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB { private static final String HTTPS_LOCALHOST = "https://localhost:8080/"; From 3d049fada19db19075415125e5be8744b5d2c825 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Wed, 22 Jun 2016 09:17:35 +0200 Subject: [PATCH 39/82] Add DMF message correlation-id to action history. Signed-off-by: kaizimmerm --- .../org/eclipse/hawkbit/simulator/amqp/SenderService.java | 1 + .../src/main/resources/application.properties | 2 +- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 5 ++--- .../org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java index 6f16ac736..f2c0e7fcb 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java @@ -58,6 +58,7 @@ public abstract class SenderService extends MessageService { } message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME); final String correlationId = UUID.randomUUID().toString(); + message.getMessageProperties().setCorrelationId(correlationId.getBytes()); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, address, correlationId); diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties index ac3f240a3..747e8ffe9 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-example-mgmt-simulator/src/main/resources/application.properties @@ -13,7 +13,7 @@ hawkbit.password=admin spring.main.show-banner=false -hawkbit.scenarios.[0].cleanRepository=true +hawkbit.scenarios.[0].cleanRepository=false hawkbit.scenarios.[0].targets=0 hawkbit.scenarios.[0].ds-name=gettingstarted-example hawkbit.scenarios.[0].distribution-sets=3 diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 73f9e14df..3f42c2937 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -70,7 +70,6 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.web.util.UriComponentsBuilder; -import com.google.common.base.Strings; import com.google.common.eventbus.EventBus; /** @@ -348,9 +347,9 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final ActionStatus actionStatus = entityFactory.generateActionStatus(); actionUpdateStatus.getMessage().forEach(actionStatus::addMessage); - if (!Strings.isNullOrEmpty(message.getMessageProperties().getCorrelationIdString())) { + if (message.getMessageProperties().getCorrelationId().length > 0) { actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " - + message.getMessageProperties().getCorrelationIdString()); + + message.getMessageProperties().getCorrelationId()); } actionStatus.setAction(action); diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java index afb3e7ff2..d951cce5d 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java @@ -46,6 +46,7 @@ public class DefaultAmqpSenderService implements AmqpSenderService { final String correlationId = UUID.randomUUID().toString(); final String exchange = extractExchange(replyTo); + message.getMessageProperties().setCorrelationId(correlationId.getBytes()); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, exchange, correlationId); From 837b62758a779a7fb6791f86af178b5c4230b457 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 22 Jun 2016 12:24:52 +0200 Subject: [PATCH 40/82] Removed closed todo Signed-off-by: Kai Zimmermann --- .../eclipse/hawkbit/repository/jpa/JpaControllerManagement.java | 1 - 1 file changed, 1 deletion(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index a4ca4d6ae..abe4dba03 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -253,7 +253,6 @@ public class JpaControllerManagement implements ControllerManagement { public Action addUpdateActionStatus(@NotNull final ActionStatus actionStatus) { final JpaAction action = (JpaAction) actionStatus.getAction(); - // TODO: test // if action is already closed we accept further status updates on if // permitted so by configuration. This is especially use full if the // action status feedback channel order from the device cannot be From 717a23671edfcb90f23e1ddb797d4db599036ee0 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 22 Jun 2016 12:31:35 +0200 Subject: [PATCH 41/82] Propr rabbit client version handling in parent POM. Signed-off-by: Kai Zimmermann --- hawkbit-dmf-amqp/pom.xml | 7 +------ pom.xml | 6 ++++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hawkbit-dmf-amqp/pom.xml b/hawkbit-dmf-amqp/pom.xml index 289d97663..9dd4f12aa 100644 --- a/hawkbit-dmf-amqp/pom.xml +++ b/hawkbit-dmf-amqp/pom.xml @@ -48,12 +48,7 @@ org.springframework.amqp spring-rabbit - - - com.rabbitmq - amqp-client - 3.6.2 - + org.springframework.security spring-security-web diff --git a/pom.xml b/pom.xml index f50afa0ab..8e49bd9df 100644 --- a/pom.xml +++ b/pom.xml @@ -69,6 +69,7 @@ 5.2.4.Final 1.2.0.RELEASE 1.6.0.RELEASE + 3.6.2 0.18.0.RELEASE Fowler-SR1 @@ -526,6 +527,11 @@ org.eclipse.persistence.jpa ${eclipselink.version} + + com.rabbitmq + amqp-client + ${rabbitmq.version} + cz.jirutka.rsql From 9226f514d230e7af7d48c24df1a6a7211afce419 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 22 Jun 2016 13:36:22 +0200 Subject: [PATCH 42/82] add spring security eval expression for system_monitor permission Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/im/authentication/SpPermission.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index ce6bc7c40..139954538 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -396,6 +396,12 @@ public final class SpPermission { public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION + HAS_AUTH_SUFFIX; + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#SYSTEM_MONITOR} + */ + public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX; + private SpringEvalExpressions() { // utility class } From aef2e3450a6278f94ec087c3f1ae441c34c9c16b Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 22 Jun 2016 15:46:43 +0200 Subject: [PATCH 43/82] remove special health security check because this can be made with spring security out-of-the box Signed-off-by: Michael Hirsch --- .../SecurityManagedConfiguration.java | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index 0b68246ff..1e4dbfb27 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -271,20 +271,6 @@ public class SecurityManagedConfiguration { return filterRegBean; } - /** - * Security configuration for the REST management API of the health url. - */ - @Configuration - @Order(310) - public static class HealthSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { - - @Override - protected void configure(final HttpSecurity http) throws Exception { - http.regexMatcher("/system/health").csrf().disable().httpBasic().and().sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS); - } - } - /** * Security configuration for the REST management API. */ @@ -310,7 +296,7 @@ public class SecurityManagedConfiguration { final BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint(); basicAuthEntryPoint.setRealmName(springSecurityProperties.getBasic().getRealm()); - HttpSecurity httpSec = http.regexMatcher("\\/rest.*|\\/system.*").csrf().disable(); + HttpSecurity httpSec = http.regexMatcher("\\/rest.*|\\/system/admin.*").csrf().disable(); if (springSecurityProperties.isRequireSsl()) { httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and(); } @@ -337,9 +323,7 @@ public class SecurityManagedConfiguration { SessionManagementFilter.class) .authorizeRequests().anyRequest().authenticated() .antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**") - .hasAnyAuthority(SpPermission.SYSTEM_ADMIN) - .antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/**") - .hasAnyAuthority(SpPermission.SYSTEM_DIAG); + .hasAnyAuthority(SpPermission.SYSTEM_ADMIN); httpSec.httpBasic().and().exceptionHandling().authenticationEntryPoint(basicAuthEntryPoint); } From 11f2232247276409643e7c4ebedcb8f482cd5061 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 22 Jun 2016 15:47:38 +0200 Subject: [PATCH 44/82] add prefixed ROLE_ to granted authorities to work with out-of-the-box spring security Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/im/authentication/PermissionUtils.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionUtils.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionUtils.java index ae8b604bb..98cde9642 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionUtils.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/PermissionUtils.java @@ -36,6 +36,9 @@ public final class PermissionUtils { for (final String role : roles) { authorities.add(new SimpleGrantedAuthority(role)); + // add spring security ROLE authority which is indicated by the + // `ROLE_` prefix + authorities.add(new SimpleGrantedAuthority("ROLE_" + role)); } return authorities; From 27005b1ae74eab7e88ae116c5c24f9e0813022ad Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 22 Jun 2016 17:33:09 +0200 Subject: [PATCH 45/82] fix test Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/im/authentication/PermissionTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java index bca7fd1c1..2c948206e 100644 --- a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/im/authentication/PermissionTest.java @@ -36,7 +36,8 @@ public final class PermissionTest { final Collection allAuthorities = SpPermission.getAllAuthorities(); final List allAuthoritiesList = PermissionUtils.createAllAuthorityList(); assertThat(allAuthorities).hasSize(allPermission); - assertThat(allAuthoritiesList).hasSize(allPermission); + // times 2 because we add also all authorities as prefix 'ROLE_'; + assertThat(allAuthoritiesList).hasSize(allPermission * 2); assertThat(allAuthoritiesList.stream().map(authority -> authority.getAuthority()).collect(Collectors.toList())) .containsAll(allAuthorities); @@ -46,7 +47,8 @@ public final class PermissionTest { .getAllAuthorities(SpPermission.SYSTEM_ADMIN, SpPermission.SYSTEM_DIAG, SpPermission.SYSTEM_MONITOR)); assertThat(authoritiesWithoutSystem).hasSize(permissionWithoutSystem); - assertThat(authoritiesListWithoutSystem).hasSize(permissionWithoutSystem); + // times 2 because we add also all authorities as prefix 'ROLE_'; + assertThat(authoritiesListWithoutSystem).hasSize(permissionWithoutSystem * 2); assertThat(authoritiesListWithoutSystem.stream().map(authority -> authority.getAuthority()) .collect(Collectors.toList())).containsAll(authoritiesWithoutSystem); From fa2477f5cb1fe83f2840caa358b9396226c94c1b Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Thu, 23 Jun 2016 09:02:05 +0200 Subject: [PATCH 46/82] Fixed nullpointer exception and optimized the code here and there. Signed-off-by: kaizimmerm --- .../scenarios/ConfigurableScenario.java | 23 +++++++++------- .../client/scenarios/upload/ArtifactFile.java | 9 +++++-- .../upload/FeignMultipartEncoder.java | 16 +++-------- .../amqp/AmqpMessageHandlerService.java | 27 ++++++++++++------- .../jpa/JpaControllerManagement.java | 4 +-- 5 files changed, 42 insertions(+), 37 deletions(-) diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java index 2cb339a1f..a09459e07 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/ConfigurableScenario.java @@ -42,6 +42,8 @@ import org.springframework.beans.factory.annotation.Qualifier; */ public class ConfigurableScenario { + private static final int PAGE_SIZE = 100; + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurableScenario.class); private final MgmtDistributionSetClientResource distributionSetResource; @@ -109,25 +111,25 @@ public class ConfigurableScenario { private void deleteSoftwareModules() { PagedList modules; do { - modules = softwareModuleResource.getSoftwareModules(0, 100, null, null).getBody(); + modules = softwareModuleResource.getSoftwareModules(0, PAGE_SIZE, null, null).getBody(); modules.getContent().forEach(module -> softwareModuleResource.deleteSoftwareModule(module.getModuleId())); - } while (modules.getTotal() > 100); + } while (modules.getTotal() > PAGE_SIZE); } private void deleteDistributionSets() { PagedList distributionSets; do { - distributionSets = distributionSetResource.getDistributionSets(0, 100, null, null).getBody(); + distributionSets = distributionSetResource.getDistributionSets(0, PAGE_SIZE, null, null).getBody(); distributionSets.getContent().forEach(set -> distributionSetResource.deleteDistributionSet(set.getDsId())); - } while (distributionSets.getTotal() > 100); + } while (distributionSets.getTotal() > PAGE_SIZE); } private void deleteTargets() { PagedList targets; do { - targets = targetResource.getTargets(0, 100, null, null).getBody(); + targets = targetResource.getTargets(0, PAGE_SIZE, null, null).getBody(); targets.getContent().forEach(target -> targetResource.deleteTarget(target.getControllerId())); - } while (targets.getTotal() > 100); + } while (targets.getTotal() > PAGE_SIZE); } private void runRollouts(final Scenario scenario) { @@ -217,10 +219,11 @@ public class ConfigurableScenario { private void createTargets(final Scenario scenario) { LOGGER.info("Creating {} targets", scenario.getTargets()); - for (int i = 0; i < scenario.getTargets() / 100; i++) { - targetResource.createTargets(new TargetBuilder().controllerId(scenario.getTargetName()) - .address(scenario.getTargetAddress()).buildAsList(i * 100, - (i + 1) * 100 > scenario.getTargets() ? (scenario.getTargets() - (i * 100)) : 100)); + for (int i = 0; i < (scenario.getTargets() / PAGE_SIZE); i++) { + targetResource.createTargets( + new TargetBuilder().controllerId(scenario.getTargetName()).address(scenario.getTargetAddress()) + .buildAsList(i * PAGE_SIZE, (i + 1) * PAGE_SIZE > scenario.getTargets() + ? (scenario.getTargets() - (i * PAGE_SIZE)) : PAGE_SIZE)); } LOGGER.info("Creating {} targets -> Done", scenario.getTargets()); diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java index adad1fe77..379455580 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/ArtifactFile.java @@ -12,11 +12,16 @@ import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.Optional; import org.springframework.util.Assert; import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartFile; +/** + * Implementation for {@link MultipartFile} for hawkBit artifact upload. + * + */ public class ArtifactFile implements MultipartFile { private final String name; @@ -55,9 +60,9 @@ public class ArtifactFile implements MultipartFile { final byte[] content) { Assert.hasLength(name, "Name must not be null"); this.name = name; - this.originalFilename = originalFilename != null ? originalFilename : ""; + this.originalFilename = Optional.ofNullable(originalFilename).orElse(""); this.contentType = contentType; - this.content = content != null ? content : new byte[0]; + this.content = Optional.ofNullable(content).orElse(new byte[0]); } @Override diff --git a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java index 00424c5e5..5d1e43e96 100644 --- a/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java +++ b/examples/hawkbit-example-mgmt-simulator/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/upload/FeignMultipartEncoder.java @@ -40,7 +40,7 @@ public class FeignMultipartEncoder implements Encoder { private final HttpHeaders multipartHeaders = new HttpHeaders(); private final HttpHeaders jsonHeaders = new HttpHeaders(); - public static final Charset UTF_8 = Charset.forName("UTF-8"); + private static final Charset UTF_8 = Charset.forName("UTF-8"); public FeignMultipartEncoder() { multipartHeaders.setContentType(MediaType.MULTIPART_FORM_DATA); @@ -48,11 +48,8 @@ public class FeignMultipartEncoder implements Encoder { } @Override - public void encode(final Object object, final Type bodyType, final RequestTemplate template) - throws EncodeException { - + public void encode(final Object object, final Type bodyType, final RequestTemplate template) { encodeMultipartFormRequest(object, template); - } private void encodeMultipartFormRequest(final Object value, final RequestTemplate template) { @@ -66,8 +63,7 @@ public class FeignMultipartEncoder implements Encoder { } @SuppressWarnings("unchecked") - private void encodeRequest(final Object value, final HttpHeaders requestHeaders, final RequestTemplate template) - throws EncodeException { + private void encodeRequest(final Object value, final HttpHeaders requestHeaders, final RequestTemplate template) { final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); final HttpOutputMessage dummyRequest = new HttpOutputMessageImpl(outputStream, requestHeaders); try { @@ -150,12 +146,6 @@ public class FeignMultipartEncoder implements Encoder { return this.filename; } - @Override - public InputStream getInputStream() throws IOException, IllegalStateException { - return super.getInputStream(); // To change body of generated - // methods, choose Tools | Templates. - } - @Override public long contentLength() throws IOException { return size; diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 3f42c2937..27cbc0f69 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -14,6 +14,7 @@ import java.util.Collections; import java.util.List; import java.util.UUID; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.api.HostnameResolver; import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; @@ -344,16 +345,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final ActionUpdateStatus actionUpdateStatus = convertMessage(message, ActionUpdateStatus.class); final Action action = checkActionExist(message, actionUpdateStatus); - final ActionStatus actionStatus = entityFactory.generateActionStatus(); - actionUpdateStatus.getMessage().forEach(actionStatus::addMessage); - - if (message.getMessageProperties().getCorrelationId().length > 0) { - actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " - + message.getMessageProperties().getCorrelationId()); - } - - actionStatus.setAction(action); - actionStatus.setOccurredAt(System.currentTimeMillis()); + final ActionStatus actionStatus = createActionStatus(message, actionUpdateStatus, action); switch (actionUpdateStatus.getActionStatus()) { case DOWNLOAD: @@ -391,6 +383,21 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } } + private ActionStatus createActionStatus(final Message message, final ActionUpdateStatus actionUpdateStatus, + final Action action) { + final ActionStatus actionStatus = entityFactory.generateActionStatus(); + actionUpdateStatus.getMessage().forEach(actionStatus::addMessage); + + if (ArrayUtils.isNotEmpty(message.getMessageProperties().getCorrelationId())) { + actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " + + message.getMessageProperties().getCorrelationId()); + } + + actionStatus.setAction(action); + actionStatus.setOccurredAt(System.currentTimeMillis()); + return actionStatus; + } + private Action getUpdateActionStatus(final ActionStatus actionStatus) { if (actionStatus.getStatus().equals(Status.CANCELED)) { return controllerManagement.addCancelActionStatus(actionStatus); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index abe4dba03..b9dfce105 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -253,8 +253,8 @@ public class JpaControllerManagement implements ControllerManagement { public Action addUpdateActionStatus(@NotNull final ActionStatus actionStatus) { final JpaAction action = (JpaAction) actionStatus.getAction(); - // if action is already closed we accept further status updates on if - // permitted so by configuration. This is especially use full if the + // if action is already closed we accept further status updates if + // permitted so by configuration. This is especially useful if the // action status feedback channel order from the device cannot be // guaranteed. However, if an action is closed we do not accept further // close messages. From bb1d3a2668df55761c56f63177f3871ad6dd6f85 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Thu, 23 Jun 2016 09:15:40 +0200 Subject: [PATCH 47/82] Remove whitespace. Signed-off-by: kaizimmerm --- hawkbit-dmf-amqp/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/pom.xml b/hawkbit-dmf-amqp/pom.xml index 9dd4f12aa..c2ed7c213 100644 --- a/hawkbit-dmf-amqp/pom.xml +++ b/hawkbit-dmf-amqp/pom.xml @@ -48,7 +48,7 @@ org.springframework.amqp spring-rabbit - + org.springframework.security spring-security-web From f567461993832ac54fc35eb414a9d6d7566ff861 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 23 Jun 2016 09:33:43 +0200 Subject: [PATCH 48/82] correct save button enabled when changes exists. Changed lower/uppercase spelling Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 4 +- .../CreateUpdateSoftwareTypeLayout.java | 3 +- .../hawkbit/ui/common/CommonDialogWindow.java | 72 ++++++--- .../ui/components/SPUIComponentProvider.java | 4 +- .../ui/decorators/SPUIWindowDecorator.java | 4 +- .../CreateUpdateDistSetTypeLayout.java | 3 +- .../AbstractCreateUpdateTagLayout.java | 18 ++- .../ui/layouts/CreateUpdateTypeLayout.java | 3 +- .../DistributionAddUpdateWindowLayout.java | 13 +- .../footer/ActionTypeOptionGroupLayout.java | 2 + .../TargetAddUpdateWindowLayout.java | 6 +- .../rollout/AddUpdateRolloutWindowLayout.java | 150 +++++++++++++++--- .../ui/rollout/rollout/RolloutListGrid.java | 4 +- .../ui/rollout/rollout/RolloutListHeader.java | 2 +- .../src/main/resources/messages.properties | 4 +- .../src/main/resources/messages_de.properties | 4 +- .../src/main/resources/messages_en.properties | 4 +- 17 files changed, 223 insertions(+), 77 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index a9baad65b..43ccbe36f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -193,7 +193,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se oldVendorValue = null; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -223,7 +223,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout)); + getMandatoryFields(formLayout), null); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.focus(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 8578ad2a4..9a87c625d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -132,7 +132,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), + getEditedFields()); } private Map getMandatoryFields() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 4388ee98a..142cd3998 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -74,6 +74,8 @@ public class CommonDialogWindow extends Window implements Serializable { private Map requiredFields; + private final Map editedFields; + @Autowired private I18N i18n; @@ -93,7 +95,7 @@ public class CommonDialogWindow extends Window implements Serializable { */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, - final Map requiredFields) { + final Map requiredFields, final Map editedFields) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -102,6 +104,7 @@ public class CommonDialogWindow extends Window implements Serializable { this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; this.requiredFields = requiredFields; + this.editedFields = editedFields; init(); } @@ -110,32 +113,32 @@ public class CommonDialogWindow extends Window implements Serializable { if (StringUtils.isNotBlank(event.getText())) { if (StringUtils.isNotBlank(textfield.getCaption())) { - getRequiredFields().put(textfield.getCaption(), Boolean.TRUE); + requiredFields.put(textfield.getCaption(), Boolean.TRUE); } getRequiredFields().put(textfield.getId(), Boolean.TRUE); } else { if (StringUtils.isNotBlank(textfield.getCaption())) { - getRequiredFields().put(textfield.getCaption(), Boolean.FALSE); + requiredFields.put(textfield.getCaption(), Boolean.FALSE); } - getRequiredFields().put(textfield.getId(), Boolean.FALSE); + requiredFields.put(textfield.getId(), Boolean.FALSE); } - checkMandatoryFields(); + checkMandatoryFieldsFilled(); } public void checkMandatoryComboBox(final ValueChangeEvent event, final AbstractSelect select) { if (event.getProperty().getValue() != null) { if (StringUtils.isNotBlank(select.getCaption())) { - getRequiredFields().put(select.getCaption(), Boolean.TRUE); + requiredFields.put(select.getCaption(), Boolean.TRUE); } - getRequiredFields().put(select.getId(), Boolean.TRUE); + requiredFields.put(select.getId(), Boolean.TRUE); } else { if (StringUtils.isNotBlank(select.getCaption())) { - getRequiredFields().put(select.getCaption(), Boolean.FALSE); + requiredFields.put(select.getCaption(), Boolean.FALSE); } - getRequiredFields().put(select.getId(), Boolean.FALSE); + requiredFields.put(select.getId(), Boolean.FALSE); } - checkMandatoryFields(); + checkMandatoryFieldsFilled(); } /** @@ -143,7 +146,7 @@ public class CommonDialogWindow extends Window implements Serializable { * mandatory fields are filled the save button is enabled. Otherwise the * save button is disabled. */ - private void checkMandatoryFields() { + private void checkMandatoryFieldsFilled() { for (final Map.Entry entry : requiredFields.entrySet()) { if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { @@ -154,35 +157,56 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setEnabled(true); } - public void updateRequiredFields(final String fieldId, final Boolean filled) { + private void checkExistsChanges() { - getRequiredFields().put(fieldId, filled); - checkMandatoryFields(); + if (editedFields == null) { + return; + } + for (final Map.Entry entry : editedFields.entrySet()) { + if (entry.getValue() != null && entry.getValue().equals(Boolean.TRUE)) { + saveButton.setEnabled(true); + return; + } + } + saveButton.setEnabled(false); } - public void checkChanges(final String newText, final String oldText) { + public void updateRequiredFields(final String fieldId, final Boolean filled) { + + requiredFields.put(fieldId, filled); + checkMandatoryFieldsFilled(); + } + + public void checkChanges(final String fieldName, final String newText, final String oldText) { if ((StringUtils.isNotBlank(newText) && !newText.equals(oldText)) || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText))) { - saveButton.setEnabled(true); + editedFields.put(fieldName, Boolean.TRUE); } else { - saveButton.setEnabled(false); + editedFields.put(fieldName, Boolean.FALSE); } + checkExistsChanges(); } - public void checkColorChange(final Color newColor, final Color oldColor) { + public void checkColorChange(final String fieldName, final Color newColor, final Color oldColor) { if (newColor.equals(oldColor)) { - setSaveButtonEnabled(false); + editedFields.put(fieldName, Boolean.FALSE); } else { - setSaveButtonEnabled(true); + editedFields.put(fieldName, Boolean.TRUE); } + checkExistsChanges(); } - public void resetRequiredFieldsValues() { - // Reset mandatory fields are filled marker - if (getRequiredFields() != null) { - for (final Map.Entry entry : getRequiredFields().entrySet()) { + public void resetMandatoryAndEditedFields() { + resetFields(requiredFields); + resetFields(editedFields); + } + + private void resetFields(final Map fields) { + // Reset mandatory fields are filled marker / fields are edited marker + if (fields != null) { + for (final Map.Entry entry : fields.entrySet()) { entry.setValue(null); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 3ba71fce5..ffc0de8ee 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -154,9 +154,9 @@ public final class SPUIComponentProvider { public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields) { + final Map requiredFields, final Map editedFields) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink, requiredFields); + cancelButtonClickListener, helpLink, requiredFields, editedFields); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index f9ce37158..b627851db 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -47,10 +47,10 @@ public final class SPUIWindowDecorator { public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields) { + final Map requiredFields, final Map editedFields) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, requiredFields); + cancelButtonClickListener, requiredFields, editedFields); if (null != id) { window.setId(id); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 4b97ce7dd..b71eaac23 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -677,7 +677,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields()); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), + getEditedFields()); } private Map getMandatoryFields() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 720f61cff..f7a067bfd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -115,8 +115,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected void createWindow() { reset(); - setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields())); + setWindow( + SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, + this, this::save, this::discard, null, getMandatoryFields(), getEditedFields())); } private Map getMandatoryFields() { @@ -131,6 +132,13 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent return requiredFields; } + protected Map getEditedFields() { + final Map changeMap = new HashMap<>(); + changeMap.put(tagDesc.getCaption(), Boolean.FALSE); + changeMap.put(colorPickerLayout.getId(), Boolean.FALSE); + return changeMap; + } + /** * Save new tag / update new tag. * @@ -213,7 +221,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected void listenerTagDescTextAreaChanged(final TextChangeEvent event) { - window.checkChanges(event.getText(), tagDescOriginal); + window.checkChanges(tagDesc.getCaption(), event.getText(), tagDescOriginal); } protected void buildLayout() { @@ -375,7 +383,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagPreviewBtnClicked = false; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -466,7 +474,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); } protected void closeWindow() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index f2ef71af1..ea77d885b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -186,7 +186,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); } /** @@ -206,6 +206,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { optiongroup = new OptionGroup("Select Action"); + optiongroup.setId(SPUIComponentIdProvider.OPTION_GROUP); optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL); optiongroup.addStyleName("custom-option-group"); optiongroup.setNullSelectionAllowed(false); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 82cf2390c..4a6a29e93 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -179,11 +179,15 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void listenerDistNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, distNameTextField); + if (!editDistribution) { + window.checkMandatoryTextField(event, distNameTextField); + } } private void listenerDistVersionTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, distVersionTextField); + if (!editDistribution) { + window.checkMandatoryTextField(event, distVersionTextField); + } } /** @@ -410,7 +414,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { changedComponents.clear(); if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -519,9 +523,8 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { resetComponents(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields()); + null, getMandatoryFields(), null); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); - return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java index de0938e7e..bc27e7aa3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ActionTypeOptionGroupLayout.java @@ -17,6 +17,7 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; +import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroup; import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent; @@ -78,6 +79,7 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout { private void createOptionGroup() { actionTypeOptionGroup = new FlexibleOptionGroup(); + actionTypeOptionGroup.setId(SPUIComponentIdProvider.ROLLOUT_ACTION_BUTTON_ID); actionTypeOptionGroup.addItem(ActionTypeOption.SOFT); actionTypeOptionGroup.addItem(ActionTypeOption.FORCED); actionTypeOptionGroup.addItem(ActionTypeOption.AUTO_FORCED); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 9bd3972f0..8ea8665d6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -244,7 +244,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields()); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null); return window; } @@ -259,7 +259,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } return requiredFields; } - + /** * clear all fields of Target Edit Window. */ @@ -274,7 +274,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { editTarget = Boolean.FALSE; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 2e419724b..566ac4528 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -150,26 +150,47 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; + private Boolean updateMode = Boolean.FALSE; + + private String distributionSetOriginal; + + private Object actionGroupOriginal; + + private String rolloutNameOriginal; + + private String errorThresholdOriginal;; + + private String triggerThresholdOriginal; + + private String descriptionOriginal; + /** * Create components and layout. */ public void init() { - setSizeUndefined(); createRequiredComponents(); buildLayout(); } public CommonDialogWindow getWindow() { - window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields()); + uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields()); return window; } - private Map getMandatoryFields() { + public CommonDialogWindow createUpdateWindow() { + updateMode = Boolean.TRUE; + return getWindow(); + } + public CommonDialogWindow createAddWindow() { + updateMode = Boolean.FALSE; + return getWindow(); + } + + private Map getMandatoryFields() { final Map requiredFields = new HashMap<>(); requiredFields.put(rolloutName.getId(), null); requiredFields.put(distributionSet.getId(), null); @@ -195,16 +216,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { setDefaultSaveStartGroupOption(); totalTargetsLabel.setVisible(false); groupSizeLabel.setVisible(false); - removeComponent(targetFilterQuery); - if (getComponent(1, 3) == null) { - addComponent(targetFilterQueryCombo, 1, 3); - } + removeComponent(1, 2); + addComponent(targetFilterQueryCombo, 1, 2); actionTypeOptionGroupLayout.selectDefaultOption(); totalTargetsCount = 0L; rolloutForEdit = null; if (window != null) { - window.resetRequiredFieldsValues(); + window.resetMandatoryAndEditedFields(); } } @@ -284,7 +303,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroups = createNoOfGroupsField(); groupSizeLabel = createGroupSizeLabel(); - triggerThreshold = createTriggerThresold(); + triggerThreshold = createTriggerThreshold(); errorThreshold = createErrorThreshold(); description = createDescription(); errorThresholdOptionGroup = createErrorThresholdOptionGroup(); @@ -293,6 +312,20 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsLabel = createTotalTargetsLabel(); targetFilterQuery = createTargetFilterQuery(); actionTypeOptionGroupLayout.addStyleName(SPUIStyleDefinitions.ROLLOUT_ACTION_TYPE_LAYOUT); + actionTypeOptionGroupLayout.getActionTypeOptionGroup() + .addValueChangeListener(this::listenerActionGroupValueChanged); + } + + private void listenerActionGroupValueChanged(final ValueChangeEvent event) { + if (window != null) { + if (!updateMode) { + window.checkMandatoryComboBox(event, actionTypeOptionGroupLayout.getActionTypeOptionGroup()); + } + if (event.getProperty().getValue() != null) { + window.checkChanges(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), + event.getProperty().getValue().toString(), actionGroupOriginal.toString()); + } + } } private Label createGroupSizeLabel() { @@ -578,9 +611,20 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { descriptionField.setId(SPUIComponentIdProvider.ROLLOUT_DESCRIPTION_ID); descriptionField.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); descriptionField.setSizeUndefined(); + descriptionField.addTextChangeListener(this::listenerDescriptionTextFieldChanged); return descriptionField; } + private void listenerDescriptionTextFieldChanged(final TextChangeEvent event) { + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, description); + return; + } + window.checkChanges(description.getId(), event.getText(), descriptionOriginal); + } + } + private TextField createErrorThreshold() { final TextField errorField = getTextfield("prompt.error.threshold"); errorField.addValidator(new ThresholdFieldValidator()); @@ -592,11 +636,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerErrorThresholdTextFieldChanged(final TextChangeEvent event) { - - window.checkMandatoryTextField(event, errorThreshold); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, errorThreshold); + return; + } + window.checkChanges(errorThreshold.getId(), event.getText(), errorThresholdOriginal); + } } - private TextField createTriggerThresold() { + private TextField createTriggerThreshold() { final TextField thresholdField = getTextfield("prompt.tigger.threshold"); thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); thresholdField.addValidator(new ThresholdFieldValidator()); @@ -607,7 +656,13 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerTriggerThresholdTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, triggerThreshold); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, triggerThreshold); + return; + } + window.checkChanges(triggerThreshold.getId(), event.getText(), triggerThresholdOriginal); + } } private TextField createNoOfGroupsField() { @@ -622,7 +677,13 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerNoOfGroupsTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, noOfGroups); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, noOfGroups); + return; + } + window.checkChanges(noOfGroups.getId(), event.getText(), noOfGroups.getValue()); + } } private void onGroupNumberChange() { @@ -647,7 +708,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerDistributionSetChanged(final ValueChangeEvent event) { - window.checkMandatoryComboBox(event, distributionSet); + if (window != null) { + if (!updateMode) { + window.checkMandatoryComboBox(event, distributionSet); + return; + } + if (event.getProperty().getValue() != null) { + window.checkChanges(distributionSet.getId(), event.getProperty().getValue().toString(), + distributionSetOriginal); + } + } } private void populateDistributionSet() { @@ -673,7 +743,13 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void listenerRolloutNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, rolloutName); + if (window != null) { + if (!updateMode) { + window.checkMandatoryTextField(event, rolloutName); + return; + } + window.checkChanges(rolloutName.getId(), event.getText(), rolloutNameOriginal); + } } private String getRolloutName() { @@ -691,7 +767,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public void validate(final Object value) { try { if (HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null) { + || (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null + && targetFilterQuery.getValue() == null)) { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { @@ -781,12 +858,42 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroups.setEnabled(false); targetFilterQuery.setValue(rolloutForEdit.getTargetFilterQuery()); - removeComponent(targetFilterQueryCombo); - addComponent(targetFilterQuery, 1, 3); + removeComponent(1, 2); + addComponent(targetFilterQuery, 1, 2); totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(rolloutForEdit.getTargetFilterQuery()); totalTargetsLabel.setValue(getTotalTargetMessage()); totalTargetsLabel.setVisible(true); + + setOriginalValues(); + } + + private void setOriginalValues() { + distributionSetOriginal = distributionSet.getValue().toString(); + actionGroupOriginal = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); + rolloutNameOriginal = rolloutName.getValue(); + triggerThresholdOriginal = triggerThreshold.getValue(); + errorThresholdOriginal = errorThreshold.getValue(); + descriptionOriginal = description.getValue(); + } + + private Map getEditedFields() { + final Map changeMap = new HashMap<>(); + if (rolloutForEdit == null) { + return changeMap; + } + if (rolloutForEdit.getStatus() != RolloutStatus.READY) { + changeMap.put(rolloutName.getId(), Boolean.FALSE); + changeMap.put(description.getId(), Boolean.FALSE); + } else { + changeMap.put(rolloutName.getId(), Boolean.FALSE); + changeMap.put(distributionSet.getId(), Boolean.FALSE); + changeMap.put(triggerThreshold.getId(), Boolean.FALSE); + changeMap.put(errorThreshold.getId(), Boolean.FALSE); + changeMap.put(description.getId(), Boolean.FALSE); + changeMap.put(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), Boolean.FALSE); + } + return changeMap; } private void disableRequiredFieldsOnEdit() { @@ -852,7 +959,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public String getValue() { return value; } - } enum ERRORTHRESOLDOPTIONS { @@ -870,6 +976,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public String getValue() { return value; } - } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 20c2ca710..d3b17da5f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.grid.AbstractGrid; import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData; import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer; @@ -62,7 +63,6 @@ import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.UI; -import com.vaadin.ui.Window; import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; import com.vaadin.ui.renderers.HtmlRenderer; @@ -438,7 +438,7 @@ public class RolloutListGrid extends AbstractGrid { private void onUpdate(final ContextMenuData contextMenuData) { addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId()); - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); + final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.createUpdateWindow(); addTargetWindow.setCaption(i18n.get("caption.update.rollout")); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 1a3d2d7a5..22c57740f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -92,7 +92,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { addUpdateRolloutWindow.resetComponents(); - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); + final Window addTargetWindow = addUpdateRolloutWindow.createAddWindow(); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 5b3ad793b..c18815b2b 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -468,10 +468,10 @@ rollout.group.label.target.truncated = {0} targets has been truncated in the lis prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold -prompt.distribution.set = Distribution set +prompt.distribution.set = Distribution Set caption.configure.rollout = Configure Rollout caption.update.rollout = Update Rollout -prompt.target.filter = Custom target filter +prompt.target.filter = Custom Target Filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists. diff --git a/hawkbit-ui/src/main/resources/messages_de.properties b/hawkbit-ui/src/main/resources/messages_de.properties index 2ac5ed9c2..2eab56ffa 100644 --- a/hawkbit-ui/src/main/resources/messages_de.properties +++ b/hawkbit-ui/src/main/resources/messages_de.properties @@ -436,7 +436,7 @@ header.rolloutgroup.target.message = Messages rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1} -distribution.details.header = Distribution set +distribution.details.header = Distribution Set target.details.header = Target header.caption.mandatory = Mandatory header.caption.typename = SoftwareModuleType @@ -461,7 +461,7 @@ prompt.error.threshold = Error threshold prompt.distribution.set = Distribution Set caption.configure.rollout = Configure Rollout caption.update.rollout = Update Rollout -prompt.target.filter = Custom target filter +prompt.target.filter = Custom Target Filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists. diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index 459695844..b1a6bb970 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -448,10 +448,10 @@ menu.title = Software Provisioning prompt.number.of.groups = Number of groups prompt.tigger.threshold = Trigger threshold prompt.error.threshold = Error threshold -prompt.distribution.set = Distribution set +prompt.distribution.set = Distribution Set caption.configure.rollout = Configure Rollout caption.update.rollout = Update Rollout -prompt.target.filter = Custom target filter +prompt.target.filter = Custom Target Filter message.rollout.nonzero.group.number = Number of groups must be greater than zero message.rollout.max.group.number = Number of groups must not be greater than 500 message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists. From a9ebb763f6f9886e425f45af6e740089c5cbfe46 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 23 Jun 2016 11:25:32 +0200 Subject: [PATCH 49/82] Add i18n to CommonDialogWindow constructor Signed-off-by: Melanie Retter --- .../smtable/SoftwareModuleAddUpdateWindow.java | 2 +- .../smtype/CreateUpdateSoftwareTypeLayout.java | 2 +- .../eclipse/hawkbit/ui/common/CommonDialogWindow.java | 10 ++++------ .../hawkbit/ui/components/SPUIComponentProvider.java | 4 ++-- .../hawkbit/ui/decorators/SPUIWindowDecorator.java | 5 +++-- .../disttype/CreateUpdateDistSetTypeLayout.java | 5 ++--- .../ui/layouts/AbstractCreateUpdateTagLayout.java | 2 +- .../dstable/DistributionAddUpdateWindowLayout.java | 2 +- .../targettable/TargetAddUpdateWindowLayout.java | 2 +- .../rollout/rollout/AddUpdateRolloutWindowLayout.java | 3 ++- 10 files changed, 18 insertions(+), 19 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 43ccbe36f..fb03902b1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -223,7 +223,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), null); + getMandatoryFields(formLayout), null, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.focus(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 9a87c625d..bfd48113d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -133,7 +133,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), - getEditedFields()); + getEditedFields(), i18n); } private Map getMandatoryFields() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 142cd3998..05d97a0de 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -77,7 +77,7 @@ public class CommonDialogWindow extends Window implements Serializable { private final Map editedFields; @Autowired - private I18N i18n; + private final I18N i18n; /** * Constructor. @@ -95,7 +95,7 @@ public class CommonDialogWindow extends Window implements Serializable { */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, - final Map requiredFields, final Map editedFields) { + final Map requiredFields, final Map editedFields, final I18N i18n) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -105,7 +105,7 @@ public class CommonDialogWindow extends Window implements Serializable { this.cancelButtonClickListener = cancelButtonClickListener; this.requiredFields = requiredFields; this.editedFields = editedFields; - + this.i18n = i18n; init(); } @@ -259,9 +259,7 @@ public class CommonDialogWindow extends Window implements Serializable { private void createMandatoryLabel() { if (existsMandatoryFieldsInWindowContent()) { - // final Label madatoryLabel = new - // Label(i18n.get("label.mandatory.field")); - final Label mandatoryLabel = new Label("* Mandatory Field"); + final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field")); mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); if (content instanceof TargetAddUpdateWindowLayout) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index ffc0de8ee..3338124c5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -154,9 +154,9 @@ public final class SPUIComponentProvider { public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields) { + final Map requiredFields, final Map editedFields, final I18N i18n) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink, requiredFields, editedFields); + cancelButtonClickListener, helpLink, requiredFields, editedFields, i18n); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index b627851db..d2d7740d3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.ui.decorators; import java.util.Map; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; @@ -47,10 +48,10 @@ public final class SPUIWindowDecorator { public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields) { + final Map requiredFields, final Map editedFields, final I18N i18n) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, requiredFields, editedFields); + cancelButtonClickListener, requiredFields, editedFields, i18n); if (null != id) { window.setId(id); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index b71eaac23..303ca1bb2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -318,7 +318,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator .hasNext();) { final long itemId = (Long) itemIterator.next(); - if (!selectedTableContainer.containsId(itemId)) { + if (selectedTableContainer.size() > 0 && !selectedTableContainer.containsId(itemId)) { return Boolean.TRUE; } } @@ -678,7 +678,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), - getEditedFields()); + getEditedFields(), i18n); } private Map getMandatoryFields() { @@ -692,7 +692,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } // Selected SoftwareModulesType requiredFields.put(selectedTable.getId(), null); - return requiredFields; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index f7a067bfd..195d173ed 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -117,7 +117,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent reset(); setWindow( SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, - this, this::save, this::discard, null, getMandatoryFields(), getEditedFields())); + this, this::save, this::discard, null, getMandatoryFields(), getEditedFields(), i18n)); } private Map getMandatoryFields() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 4a6a29e93..03dce184c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -523,7 +523,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { resetComponents(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields(), null); + null, getMandatoryFields(), null, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 8ea8665d6..07360ed70 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -244,7 +244,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null, i18n); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 566ac4528..c1efa9f4b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -176,7 +176,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public CommonDialogWindow getWindow() { window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), - uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields()); + uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields(), + i18n); return window; } From 0a36f23bb33d47de6532941119aad2a3f82931f1 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 24 Jun 2016 12:09:23 +0200 Subject: [PATCH 50/82] retrieve target-security-token with system-context permission Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 27cbc0f69..8c1b359a6 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -47,6 +47,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.util.IpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -105,6 +106,9 @@ public class AmqpMessageHandlerService extends BaseAmqpService { @Autowired private EntityFactory entityFactory; + @Autowired + private SystemSecurityContext systemSecurityContext; + /** * Constructor. * @@ -313,9 +317,10 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final DistributionSet distributionSet = action.getDistributionSet(); final List softwareModuleList = controllerManagement .findSoftwareModulesByDistributionSet(distributionSet); + final String targetSecurityToken = systemSecurityContext.runAsSystem(() -> target.getSecurityToken()); eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(), target.getControllerId(), action.getId(), softwareModuleList, target.getTargetInfo().getAddress(), - target.getSecurityToken())); + targetSecurityToken)); } From 128585c95e87651237b3542c1d29a37bb4e6ef03 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 24 Jun 2016 12:38:46 +0200 Subject: [PATCH 51/82] fix test Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 3 +++ .../hawkbit/amqp/AmqpMessageHandlerServiceTest.java | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 8c1b359a6..36f90adae 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -478,4 +478,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { this.entityFactory = entityFactory; } + void setSystemSecurityContext(final SystemSecurityContext systemSecurityContext) { + this.systemSecurityContext = systemSecurityContext; + } } diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 338feea62..7ef51d961 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -52,6 +52,7 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.security.SecurityTokenGenerator; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -112,6 +113,9 @@ public class AmqpMessageHandlerServiceTest { @Mock private RabbitTemplate rabbitTemplate; + @Mock + private SystemSecurityContext systemSecurityContextMock; + @Before public void before() throws Exception { messageConverter = new Jackson2JsonMessageConverter(); @@ -124,6 +128,7 @@ public class AmqpMessageHandlerServiceTest { amqpMessageHandlerService.setHostnameResolver(hostnameResolverMock); amqpMessageHandlerService.setEventBus(eventBus); amqpMessageHandlerService.setEntityFactory(entityFactoryMock); + amqpMessageHandlerService.setSystemSecurityContext(systemSecurityContextMock); } @@ -367,6 +372,8 @@ public class AmqpMessageHandlerServiceTest { when(controllerManagementMock.findSoftwareModulesByDistributionSet(Matchers.any())) .thenReturn(softwareModuleList); + when(systemSecurityContextMock.runAsSystem(anyObject())).thenReturn("securityToken"); + final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT); messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name()); final ActionUpdateStatus actionUpdateStatus = createActionUpdateStatus(ActionStatus.FINISHED, 23L); From 23cb62b9d9b7e537fa81aaed75ef2f780ee92827 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Fri, 24 Jun 2016 13:59:19 +0200 Subject: [PATCH 52/82] Fix scheduled executor, auth exchange and simulator poll. Signed-off-by: kaizimmerm --- .../simulator/DeviceSimulatorUpdater.java | 3 +- .../simulator/SimulatedDeviceFactory.java | 2 +- .../simulator/SimulationController.java | 4 - .../hawkbit/simulator/SimulatorStartup.java | 5 - .../simulator/amqp/AmqpConfiguration.java | 10 +- .../AsyncConfigurerThreadpoolProperties.java | 13 +++ .../scheduling/ExecutorAutoConfiguration.java | 50 +++++----- .../main/resources/hawkbitdefaults.properties | 3 +- .../hawkbit/amqp/AmqpConfiguration.java | 93 +++++++++++++------ .../amqp/AmqpMessageHandlerService.java | 25 ++++- .../eclipse/hawkbit/amqp/AmqpProperties.java | 24 ++++- .../hawkbit/AmqpTestConfiguration.java | 9 +- .../AmqpControllerAuthenticationTest.java | 19 ++-- .../amqp/AmqpMessageHandlerServiceTest.java | 19 ++-- .../hawkbit/dmf/amqp/api/AmqpSettings.java | 2 + .../hawkbit/dmf/amqp/api/MessageType.java | 5 - .../test/util/TestConfiguration.java | 4 +- 17 files changed, 185 insertions(+), 105 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index 0931f6f3e..81237beb7 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -99,7 +99,8 @@ public class DeviceSimulatorUpdater { // plug and play - non existing device will be auto created if (device == null) { - device = repository.add(deviceFactory.createSimulatedDevice(id, tenant, Protocol.DMF_AMQP, -1, null, null)); + device = repository + .add(deviceFactory.createSimulatedDevice(id, tenant, Protocol.DMF_AMQP, 1800, null, null)); } device.setProgress(0.0); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java index 35829c673..8d5c5e0b1 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java @@ -45,7 +45,7 @@ public class SimulatedDeviceFactory { */ public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, final Protocol protocol) { - return createSimulatedDevice(id, tenant, protocol, 30, null, null); + return createSimulatedDevice(id, tenant, protocol, 1800, null, null); } /** diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java index 3bd6b41f2..43f954c00 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java @@ -86,10 +86,6 @@ public class SimulationController { final String deviceId = name + i; repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint), gatewayToken)); - - if (protocol == Protocol.DMF_AMQP) { - spSenderService.createOrUpdateThing(tenant, deviceId); - } } return ResponseEntity.ok("Updated " + amount + " DMF connected targets!"); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java index 19367a9d4..486eb4b5e 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.simulator; import java.net.MalformedURLException; import java.net.URL; -import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; import org.eclipse.hawkbit.simulator.amqp.SpSenderService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,10 +53,6 @@ public class SimulatorStartup implements ApplicationListener arguments = getDeadLetterExchangeArgs(); arguments.putAll(getTTLMaxArgs()); - return QueueBuilder.nonDurable(amqpProperties.getReceiverConnectorQueueFromSp()).withArguments(arguments) - .build(); + return QueueBuilder.nonDurable(amqpProperties.getReceiverConnectorQueueFromSp()).autoDelete() + .withArguments(arguments).build(); } /** @@ -133,12 +133,12 @@ public class AmqpConfiguration { */ @Bean public FanoutExchange exchangeQueueToConnector() { - return new FanoutExchange(amqpProperties.getSenderForSpExchange()); + return new FanoutExchange(amqpProperties.getSenderForSpExchange(), false, true); } /** * Create the Binding - * {@link AmqpConfiguration#receiverConnectorQueueFromSp()} to + * {@link AmqpConfiguration#receiverConnectorQueueFromHawkBit()} to * {@link AmqpConfiguration#exchangeQueueToConnector()}. * * @return the binding and create the queue and exchange @@ -165,7 +165,7 @@ public class AmqpConfiguration { */ @Bean public FanoutExchange exchangeDeadLetter() { - return new FanoutExchange(amqpProperties.getDeadLetterExchange()); + return new FanoutExchange(amqpProperties.getDeadLetterExchange(), false, true); } /** diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerThreadpoolProperties.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerThreadpoolProperties.java index 4425c7278..d6f3ca430 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerThreadpoolProperties.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerThreadpoolProperties.java @@ -32,6 +32,11 @@ public class AsyncConfigurerThreadpoolProperties { */ private Integer maxthreads = 20; + /** + * Core processing threads for scheduled event executor. + */ + private Integer schedulerThreads = 3; + /** * When the number of threads is greater than the core, this is the maximum * time that excess idle threads will wait for new tasks before terminating. @@ -70,4 +75,12 @@ public class AsyncConfigurerThreadpoolProperties { this.idletimeout = idletimeout; } + public Integer getSchedulerThreads() { + return schedulerThreads; + } + + public void setSchedulerThreads(final Integer schedulerThreads) { + this.schedulerThreads = schedulerThreads; + } + } diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/ExecutorAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/ExecutorAutoConfiguration.java index 0aeaf75bb..917e4e4ef 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/ExecutorAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/ExecutorAutoConfiguration.java @@ -11,6 +11,8 @@ package org.eclipse.hawkbit.autoconfigure.scheduling; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy; @@ -24,9 +26,12 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; import org.springframework.security.concurrent.DelegatingSecurityContextExecutor; +import org.springframework.security.concurrent.DelegatingSecurityContextExecutorService; +import org.springframework.security.concurrent.DelegatingSecurityContextScheduledExecutorService; import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -45,20 +50,28 @@ public class ExecutorAutoConfiguration { /** * @return ExecutorService with security context availability in thread - * execution.. + * execution. + */ + @Bean(destroyMethod = "shutdown") + @ConditionalOnMissingBean + public ExecutorService asyncExecutor() { + return new DelegatingSecurityContextExecutorService(threadPoolExecutor()); + } + + /** + * @return {@link TaskExecutor} for task execution */ @Bean @ConditionalOnMissingBean - public Executor asyncExecutor() { - return new DelegatingSecurityContextExecutor(threadPoolExecutor()); + public TaskExecutor taskExecutor() { + return new ConcurrentTaskExecutor(asyncExecutor()); } /** * @return central ThreadPoolExecutor for general purpose multi threaded * operations. Tries an orderly shutdown when destroyed. */ - @Bean(destroyMethod = "shutdown") - public ThreadPoolExecutor threadPoolExecutor() { + private ThreadPoolExecutor threadPoolExecutor() { final BlockingQueue blockingQueue = new ArrayBlockingQueue<>( asyncConfigurerProperties.getQueuesize()); return new ThreadPoolExecutor(asyncConfigurerProperties.getCorethreads(), @@ -92,31 +105,24 @@ public class ExecutorAutoConfiguration { } /** - * @return {@link TaskExecutor} for task execution + * @return {@link ScheduledExecutorService} with security context + * availability in thread execution. */ - @Bean - @ConditionalOnMissingBean - public TaskExecutor taskExecutor() { - return new ConcurrentTaskExecutor(asyncExecutor()); - } - - /** - * @return {@link ScheduledExecutorService} based on - * {@link #threadPoolTaskScheduler()}. - */ - @Bean + @Bean(destroyMethod = "shutdown") @ConditionalOnMissingBean public ScheduledExecutorService scheduledExecutorService() { - return threadPoolTaskScheduler().getScheduledExecutor(); + return new DelegatingSecurityContextScheduledExecutorService( + Executors.newScheduledThreadPool(asyncConfigurerProperties.getSchedulerThreads(), + new ThreadFactoryBuilder().setNameFormat("central-scheduled-executor-pool-%d").build())); } /** - * @return {@link ThreadPoolTaskScheduler} for scheduled operations. + * @return {@link TaskScheduler} for task execution */ @Bean @ConditionalOnMissingBean - public ThreadPoolTaskScheduler threadPoolTaskScheduler() { - return new ThreadPoolTaskScheduler(); + public TaskScheduler taskScheduler() { + return new ConcurrentTaskScheduler(scheduledExecutorService()); } } diff --git a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties index 9c197fbb3..cb7793168 100644 --- a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties +++ b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties @@ -41,4 +41,5 @@ hawkbit.controller.minPollingTime=00:00:30 # Configuration for RabbitMQ integration hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter_ttl hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter -hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver \ No newline at end of file +hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver +hawkbit.dmf.rabbitmq.authenticationReceiverQueue=authentication_receiver diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index c26b5547e..ae25d0086 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -8,8 +8,11 @@ */ package org.eclipse.hawkbit.amqp; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ThreadPoolExecutor; import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings; import org.slf4j.Logger; @@ -18,6 +21,7 @@ import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Queue; +import org.springframework.amqp.core.QueueBuilder; import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; @@ -51,10 +55,6 @@ public class AmqpConfiguration { @Autowired private AmqpDeadletterProperties amqpDeadletterProperties; - @Autowired - @Qualifier("threadPoolExecutor") - private ThreadPoolExecutor threadPoolExecutor; - @Autowired private ConnectionFactory rabbitConnectionFactory; @@ -66,8 +66,8 @@ public class AmqpConfiguration { private AmqpProperties amqpProperties; @Autowired - @Qualifier("threadPoolExecutor") - private ThreadPoolExecutor threadPoolExecutor; + @Qualifier("asyncExecutor") + private Executor threadPoolExecutor; @Autowired private ScheduledExecutorService scheduledExecutorService; @@ -145,26 +145,71 @@ public class AmqpConfiguration { } /** - * Create the sp receiver queue. + * Create the DMF API receiver queue for * * @return the receiver queue */ @Bean - public Queue receiverQueue() { + public Queue dmfReceiverQueue() { return new Queue(amqpProperties.getReceiverQueue(), true, false, false, amqpDeadletterProperties.getDeadLetterExchangeArgs(amqpProperties.getDeadLetterExchange())); } /** - * Create the dead letter fanout exchange. + * Create the DMF API receiver queue for authentication requests called by + * 3rd party artifact storages for download authorization by devices. + * + * @return the receiver queue + */ + @Bean + public Queue authenticationReceiverQueue() { + return QueueBuilder.nonDurable(amqpProperties.getAuthenticationReceiverQueue()).autoDelete() + .withArguments(getTTLMaxArgsAuthenticationQueue()).build(); + } + + /** + * Create DMF exchange. * * @return the fanout exchange */ @Bean - public FanoutExchange senderExchange() { + public FanoutExchange dmfSenderExchange() { return new FanoutExchange(AmqpSettings.DMF_EXCHANGE); } + /** + * Create the Binding {@link AmqpConfiguration#dmfReceiverQueue()} to + * {@link AmqpConfiguration#dmfSenderExchange()}. + * + * @return the binding and create the queue and exchange + */ + @Bean + public Binding bindDmfSenderExchangeToDmfQueue() { + return BindingBuilder.bind(dmfReceiverQueue()).to(dmfSenderExchange()); + } + + /** + * Create authentication exchange. + * + * @return the fanout exchange + */ + @Bean + public FanoutExchange authenticationExchange() { + return new FanoutExchange(AmqpSettings.AUTHENTICATION_EXCHANGE, false, true); + } + + /** + * Create the Binding + * {@link AmqpConfiguration#authenticationReceiverQueue()} to + * {@link AmqpConfiguration#authenticationExchange()}. + * + * @return the binding and create the queue and exchange + */ + @Bean + public Binding bindAuthenticationSenderExchangeToAuthenticationQueue() { + return BindingBuilder.bind(authenticationReceiverQueue()).to(authenticationExchange()); + } + /** * Create dead letter queue. * @@ -181,29 +226,18 @@ public class AmqpConfiguration { * @return the fanout exchange */ @Bean - public FanoutExchange exchangeDeadLetter() { + public FanoutExchange deadLetterExchange() { return new FanoutExchange(amqpProperties.getDeadLetterExchange()); } /** - * Create the Binding deadLetterQueue to exchangeDeadLetter. + * Create the Binding deadLetterQueue to deadLetterExchange. * * @return the binding */ @Bean - public Binding bindDeadLetterQueueToLwm2mExchange() { - return BindingBuilder.bind(deadLetterQueue()).to(exchangeDeadLetter()); - } - - /** - * Create the Binding {@link AmqpConfiguration#receiverQueue()} to - * {@link AmqpConfiguration#senderExchange()}. - * - * @return the binding and create the queue and exchange - */ - @Bean - public Binding bindSenderExchangeToSpQueue() { - return BindingBuilder.bind(receiverQueue()).to(senderExchange()); + public Binding bindDeadLetterQueueToDeadLetterExchange() { + return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()); } /** @@ -245,4 +279,11 @@ public class AmqpConfiguration { return containerFactory; } + private static Map getTTLMaxArgsAuthenticationQueue() { + final Map args = new HashMap<>(); + args.put("x-message-ttl", Duration.ofSeconds(30).toMillis()); + args.put("x-max-length", 1_000); + return args; + } + } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 27cbc0f69..7d4e08144 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -116,7 +116,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } /** - * Method to handle all incoming amqp messages. + * Method to handle all incoming DMF amqp messages. * * @param message * incoming message @@ -133,6 +133,12 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost()); } + @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory") + public Message onAuthenticationRequest(final Message message, + @Header(MessageHeaderKey.TENANT) final String tenant) { + return onAuthenticationRequest(message); + } + public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) { checkContentTypeJson(message); final SecurityContext oldContext = SecurityContextHolder.getContext(); @@ -149,8 +155,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final EventTopic eventTopic = EventTopic.valueOf(topicValue); handleIncomingEvent(message, eventTopic); break; - case AUTHENTIFICATION: - return handleAuthentifiactionMessage(message); + default: logAndThrowMessageError(message, "No handle method was found for the given message type."); } @@ -164,6 +169,20 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return null; } + public Message onAuthenticationRequest(final Message message) { + checkContentTypeJson(message); + final SecurityContext oldContext = SecurityContextHolder.getContext(); + try { + return handleAuthentifiactionMessage(message); + } catch (final IllegalArgumentException ex) { + throw new AmqpRejectAndDontRequeueException("Invalid message!", ex); + } catch (final TenantNotExistException teex) { + throw new AmqpRejectAndDontRequeueException(teex); + } finally { + SecurityContextHolder.setContext(oldContext); + } + } + private Message handleAuthentifiactionMessage(final Message message) { final DownloadResponse authentificationResponse = new DownloadResponse(); final MessageProperties messageProperties = message.getMessageProperties(); diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java index ace1fefa2..888b204e7 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java @@ -31,10 +31,16 @@ public class AmqpProperties { private String deadLetterExchange = "dmf.connector.deadletter"; /** - * DMF API receiving queue. + * DMF API receiving queue for EVENT or THING_CREATED message. */ private String receiverQueue = "dmf_receiver"; + /** + * Authentication request called by 3rd party artifact storages for download + * authorizations. + */ + private String authenticationReceiverQueue = "authentication_receiver"; + /** * Missing queue fatal. */ @@ -62,6 +68,14 @@ public class AmqpProperties { */ private int initialConcurrentConsumers = 3; + public String getAuthenticationReceiverQueue() { + return authenticationReceiverQueue; + } + + public void setAuthenticationReceiverQueue(final String authenticationReceiverQueue) { + this.authenticationReceiverQueue = authenticationReceiverQueue; + } + public int getPrefetchCount() { return prefetchCount; } @@ -147,10 +161,6 @@ public class AmqpProperties { return receiverQueue; } - public void setReceiverQueue(final String receiverQueue) { - this.receiverQueue = receiverQueue; - } - public int getRequestedHeartBeat() { return requestedHeartBeat; } @@ -159,4 +169,8 @@ public class AmqpProperties { this.requestedHeartBeat = requestedHeartBeat; } + public void setReceiverQueue(final String receiverQueue) { + this.receiverQueue = receiverQueue; + } + } diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/AmqpTestConfiguration.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/AmqpTestConfiguration.java index 075313a19..467c650be 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/AmqpTestConfiguration.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/AmqpTestConfiguration.java @@ -31,7 +31,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.task.TaskExecutor; import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.security.concurrent.DelegatingSecurityContextExecutor; +import org.springframework.security.concurrent.DelegatingSecurityContextExecutorService; import com.google.common.util.concurrent.ThreadFactoryBuilder; @@ -78,18 +78,17 @@ public class AmqpTestConfiguration { * @return ExecutorService with security context availability in thread * execution.. */ - @Bean + @Bean(destroyMethod = "shutdown") @ConditionalOnMissingBean public Executor asyncExecutor() { - return new DelegatingSecurityContextExecutor(threadPoolExecutor()); + return new DelegatingSecurityContextExecutorService(threadPoolExecutor()); } /** * @return central ThreadPoolExecutor for general purpose multi threaded * operations. Tries an orderly shutdown when destroyed. */ - @Bean(destroyMethod = "shutdown") - public ThreadPoolExecutor threadPoolExecutor() { + private ThreadPoolExecutor threadPoolExecutor() { final BlockingQueue blockingQueue = new ArrayBlockingQueue<>(10); final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 10, 1000, TimeUnit.MILLISECONDS, blockingQueue, new ThreadFactoryBuilder().setNameFormat("central-executor-pool-%d").build()); diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java index 881260579..4e08e1852 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java @@ -158,7 +158,7 @@ public class AmqpControllerAuthenticationTest { @Test @Description("Tests authentication message without principal") public void testAuthenticationMessageBadCredantialsWithoutPricipal() { - final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); + final MessageProperties messageProperties = createMessageProperties(null); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, FileResource.sha1("12345")); @@ -166,8 +166,7 @@ public class AmqpControllerAuthenticationTest { messageProperties); // test - final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(), - TENANT, "vHost"); + final Message onMessage = amqpMessageHandlerService.onAuthenticationRequest(message); // verify final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage); @@ -178,7 +177,7 @@ public class AmqpControllerAuthenticationTest { @Test @Description("Tests authentication message without wrong credential") public void testAuthenticationMessageBadCredantialsWithWrongCredential() { - final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); + final MessageProperties messageProperties = createMessageProperties(null); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, FileResource.sha1("12345")); when(tenantConfigurationManagement.getConfigurationValue( @@ -189,8 +188,7 @@ public class AmqpControllerAuthenticationTest { messageProperties); // test - final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(), - TENANT, "vHost"); + final Message onMessage = amqpMessageHandlerService.onAuthenticationRequest(message); // verify final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage); @@ -201,7 +199,7 @@ public class AmqpControllerAuthenticationTest { @Test @Description("Tests authentication message successfull") public void testSuccessfullMessageAuthentication() { - final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); + final MessageProperties messageProperties = createMessageProperties(null); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, FileResource.sha1("12345")); when(tenantConfigurationManagement.getConfigurationValue( @@ -212,8 +210,7 @@ public class AmqpControllerAuthenticationTest { messageProperties); // test - final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(), - TENANT, "vHost"); + final Message onMessage = amqpMessageHandlerService.onAuthenticationRequest(message); // verify final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage); @@ -232,7 +229,9 @@ public class AmqpControllerAuthenticationTest { private MessageProperties createMessageProperties(final MessageType type, final String replyTo) { final MessageProperties messageProperties = new MessageProperties(); - messageProperties.setHeader(MessageHeaderKey.TYPE, type.name()); + if (type != null) { + messageProperties.setHeader(MessageHeaderKey.TYPE, type.name()); + } messageProperties.setHeader(MessageHeaderKey.TENANT, TENANT); messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON); messageProperties.setReplyTo(replyTo); diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 338feea62..43d7980df 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -273,14 +273,13 @@ public class AmqpMessageHandlerServiceTest { @Test @Description("Tests that an download request is denied for an artifact which does not exists") public void authenticationRequestDeniedForArtifactWhichDoesNotExists() { - final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); + final MessageProperties messageProperties = createMessageProperties(null); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345")); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); // test - final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(), - TENANT, "vHost"); + final Message onMessage = amqpMessageHandlerService.onAuthenticationRequest(message); // verify final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage); @@ -292,7 +291,7 @@ public class AmqpMessageHandlerServiceTest { @Test @Description("Tests that an download request is denied for an artifact which is not assigned to the requested target") public void authenticationRequestDeniedForArtifactWhichIsNotAssignedToTarget() { - final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); + final MessageProperties messageProperties = createMessageProperties(null); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345")); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); @@ -303,8 +302,7 @@ public class AmqpMessageHandlerServiceTest { .thenThrow(EntityNotFoundException.class); // test - final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(), - TENANT, "vHost"); + final Message onMessage = amqpMessageHandlerService.onAuthenticationRequest(message); // verify final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage); @@ -316,7 +314,7 @@ public class AmqpMessageHandlerServiceTest { @Test @Description("Tests that an download request is allowed for an artifact which exists and assigned to the requested target") public void authenticationRequestAllowedForArtifactWhichExistsAndAssignedToTarget() throws MalformedURLException { - final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); + final MessageProperties messageProperties = createMessageProperties(null); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345")); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); @@ -334,8 +332,7 @@ public class AmqpMessageHandlerServiceTest { when(hostnameResolverMock.resolveHostname()).thenReturn(new URL("http://localhost")); // test - final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(), - TENANT, "vHost"); + final Message onMessage = amqpMessageHandlerService.onAuthenticationRequest(message); // verify final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage); @@ -411,7 +408,9 @@ public class AmqpMessageHandlerServiceTest { private MessageProperties createMessageProperties(final MessageType type, final String replyTo) { final MessageProperties messageProperties = new MessageProperties(); - messageProperties.setHeader(MessageHeaderKey.TYPE, type.name()); + if (type != null) { + messageProperties.setHeader(MessageHeaderKey.TYPE, type.name()); + } messageProperties.setHeader(MessageHeaderKey.TENANT, TENANT); messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON); messageProperties.setReplyTo(replyTo); diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/AmqpSettings.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/AmqpSettings.java index 40ba04419..364f36aa5 100644 --- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/AmqpSettings.java +++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/AmqpSettings.java @@ -18,6 +18,8 @@ public final class AmqpSettings { public static final String DMF_EXCHANGE = "dmf.exchange"; + public static final String AUTHENTICATION_EXCHANGE = "authentication.exchange"; + private AmqpSettings() { } diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/MessageType.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/MessageType.java index 8cca32b06..e66a0c8c6 100644 --- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/MessageType.java +++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/amqp/api/MessageType.java @@ -26,9 +26,4 @@ public enum MessageType { */ THING_CREATED, - /** - * The authentication type. - */ - AUTHENTIFICATION, - } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestConfiguration.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestConfiguration.java index e6a8e7686..3a7a2f73d 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestConfiguration.java @@ -31,7 +31,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.data.domain.AuditorAware; import org.springframework.scheduling.annotation.AsyncConfigurer; -import org.springframework.security.concurrent.DelegatingSecurityContextExecutor; +import org.springframework.security.concurrent.DelegatingSecurityContextExecutorService; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import com.google.common.eventbus.AsyncEventBus; @@ -99,7 +99,7 @@ public class TestConfiguration implements AsyncConfigurer { @Bean public Executor asyncExecutor() { - return new DelegatingSecurityContextExecutor(Executors.newSingleThreadExecutor()); + return new DelegatingSecurityContextExecutorService(Executors.newSingleThreadExecutor()); } @Bean From 2150f45bded5c45729c7bf6b655f4768a1202380 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 24 Jun 2016 14:51:18 +0200 Subject: [PATCH 53/82] use SecurityContext as thread local because it's delegated throug threads Signed-off-by: Michael Hirsch --- .../security/SecurityContextTenantAware.java | 101 +++++++++++++----- .../security/SystemSecurityContext.java | 18 ++-- 2 files changed, 88 insertions(+), 31 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java index 2d8ac52df..e548acb7a 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java @@ -8,13 +8,15 @@ */ package org.eclipse.hawkbit.security; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.Collection; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.context.SecurityContextImpl; /** * A {@link TenantAware} implemenation which retrieves the ID of the tenant from @@ -28,9 +30,6 @@ import org.springframework.security.core.context.SecurityContextHolder; */ public class SecurityContextTenantAware implements TenantAware { - private static final ThreadLocal TENANT_THREAD_LOCAL = new ThreadLocal<>(); - private static final ThreadLocal RUN_AS_DEPTH = new ThreadLocal<>(); - /* * (non-Javadoc) * @@ -38,9 +37,6 @@ public class SecurityContextTenantAware implements TenantAware { */ @Override public String getCurrentTenant() { - if (TENANT_THREAD_LOCAL.get() != null) { - return TENANT_THREAD_LOCAL.get(); - } final SecurityContext context = SecurityContextHolder.getContext(); if (context.getAuthentication() != null) { final Object authDetails = context.getAuthentication().getDetails(); @@ -51,29 +47,84 @@ public class SecurityContextTenantAware implements TenantAware { return null; } - /* - * (non-Javadoc) - * - * @see hawkbit.server.tenancy.TenantAware#runAsTenant(java.lang.String, - * java.util.concurrent.Callable) - */ @Override public T runAsTenant(final String tenant, final TenantRunner callable) { - AtomicInteger runAsDepth = RUN_AS_DEPTH.get(); - if (runAsDepth == null) { - runAsDepth = new AtomicInteger(1); - RUN_AS_DEPTH.set(runAsDepth); - } else { - runAsDepth.incrementAndGet(); - } - TENANT_THREAD_LOCAL.set(tenant); + final SecurityContext originalContext = SecurityContextHolder.getContext(); try { + SecurityContextHolder.setContext(buildSecurityContext(tenant)); return callable.run(); } finally { - if (runAsDepth.decrementAndGet() <= 0) { - RUN_AS_DEPTH.remove(); - TENANT_THREAD_LOCAL.remove(); - } + SecurityContextHolder.setContext(originalContext); + } + } + + private SecurityContext buildSecurityContext(final String tenant) { + final SecurityContextImpl securityContext = new SecurityContextImpl(); + securityContext.setAuthentication( + new AuthenticationDelegate(SecurityContextHolder.getContext().getAuthentication(), tenant)); + return securityContext; + } + + private class AuthenticationDelegate implements Authentication { + private static final long serialVersionUID = 1L; + + private final Authentication delegate; + private final TenantAwareAuthenticationDetails tenantAwareAuthenticationDetails; + + private AuthenticationDelegate(final Authentication delegate, final String tenant) { + this.delegate = delegate; + tenantAwareAuthenticationDetails = new TenantAwareAuthenticationDetails(tenant, false); + + } + + @Override + public boolean equals(final Object another) { + return delegate.equals(another); + } + + @Override + public String toString() { + return delegate.toString(); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public Collection getAuthorities() { + return delegate.getAuthorities(); + } + + @Override + public Object getCredentials() { + return delegate.getCredentials(); + } + + @Override + public Object getDetails() { + return tenantAwareAuthenticationDetails; + } + + @Override + public Object getPrincipal() { + return delegate.getPrincipal(); + } + + @Override + public boolean isAuthenticated() { + return delegate.isAuthenticated(); + } + + @Override + public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException { + delegate.setAuthenticated(isAuthenticated); } } } diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index 78fb5818d..c0ecb8ceb 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -72,7 +72,7 @@ public class SystemSecurityContext { logger.debug("entering system code execution"); return tenantAware.runAsTenant(tenantAware.getCurrentTenant(), () -> { try { - setSystemContext(); + setSystemContext(oldContext); return callable.call(); } catch (final Exception e) { throw Throwables.propagate(e); @@ -93,9 +93,10 @@ public class SystemSecurityContext { return SecurityContextHolder.getContext().getAuthentication() instanceof SystemCodeAuthentication; } - private static void setSystemContext() { + private static void setSystemContext(final SecurityContext oldContext) { + final Authentication oldAuthentication = oldContext.getAuthentication(); final SecurityContextImpl securityContextImpl = new SecurityContextImpl(); - securityContextImpl.setAuthentication(new SystemCodeAuthentication()); + securityContextImpl.setAuthentication(new SystemCodeAuthentication(oldAuthentication)); SecurityContextHolder.setContext(securityContextImpl); } @@ -104,6 +105,11 @@ public class SystemSecurityContext { private static final long serialVersionUID = 1L; private static final List AUTHORITIES = Collections .singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.SYSTEM_ROLE)); + private final Authentication oldAuthentication; + + private SystemCodeAuthentication(final Authentication oldAuthentication) { + this.oldAuthentication = oldAuthentication; + } @Override public String getName() { @@ -117,17 +123,17 @@ public class SystemSecurityContext { @Override public Object getCredentials() { - return null; + return oldAuthentication != null ? oldAuthentication.getCredentials() : null; } @Override public Object getDetails() { - return null; + return oldAuthentication != null ? oldAuthentication.getDetails() : null; } @Override public Object getPrincipal() { - return null; + return oldAuthentication != null ? oldAuthentication.getPrincipal() : null; } @Override From a5d84a47e070df13cfc8624330fa2f018dce0a86 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 24 Jun 2016 14:58:26 +0200 Subject: [PATCH 54/82] code beautify Signed-off-by: Michael Hirsch --- .../hawkbit/security/SecurityContextTenantAware.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java index e548acb7a..4b5fe7224 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java @@ -24,9 +24,6 @@ import org.springframework.security.core.context.SecurityContextImpl; * {@link Authentication#getDetails()} which holds the * {@link TenantAwareAuthenticationDetails} object. * - * - * - * */ public class SecurityContextTenantAware implements TenantAware { @@ -65,6 +62,11 @@ public class SecurityContextTenantAware implements TenantAware { return securityContext; } + /** + * An {@link Authentication} implementation to delegate to an existing + * {@link Authentication} object except setting the details specifically for + * a specific tenant. + */ private class AuthenticationDelegate implements Authentication { private static final long serialVersionUID = 1L; @@ -74,7 +76,6 @@ public class SecurityContextTenantAware implements TenantAware { private AuthenticationDelegate(final Authentication delegate, final String tenant) { this.delegate = delegate; tenantAwareAuthenticationDetails = new TenantAwareAuthenticationDetails(tenant, false); - } @Override From 82bdaf53ed9610a976a8441a9f663eb5db828b11 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 24 Jun 2016 15:12:24 +0200 Subject: [PATCH 55/82] Fix wrong multi part exception message in response. Hardening all exception message and classes in exception handler for reponses Signed-off-by: SirWayne --- .../hawkbit/exception/SpServerError.java | 4 -- .../resource/MgmtSoftwareModuleResource.java | 32 ++++----- .../MultiPartFileUploadException.java | 30 ++++++++ .../exception/ResponseExceptionHandler.java | 72 ++++++++++--------- 4 files changed, 82 insertions(+), 56 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java index 7d618e234..5acd11463 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java @@ -87,10 +87,6 @@ public enum SpServerError { */ SP_DS_CREATION_FAILED_MISSING_MODULE("hawkbit.server.error.distributionset.creationFailed.missingModule", "Creation if Distribution Set failed as module is missing that is configured as mandatory."), - /** - * - */ - SP_ARTIFACT_UPLOAD_FILE_LIMIT_EXCEEDED("hawkbit.server.error.artifact.uploadFailed.sizelimitexceeded", "Upload of artifact failed as the file exceeds its maximum permitted size"), /** * */ diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java index b4f1e8adb..b475c473f 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java @@ -68,28 +68,24 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi { @RequestParam(value = "md5sum", required = false) final String md5Sum, @RequestParam(value = "sha1sum", required = false) final String sha1Sum) { - Artifact result; - if (!file.isEmpty()) { - String fileName = optionalFileName; - - if (null == fileName) { - fileName = file.getOriginalFilename(); - } - - try { - result = artifactManagement.createLocalArtifact(file.getInputStream(), softwareModuleId, fileName, - md5Sum == null ? null : md5Sum.toLowerCase(), sha1Sum == null ? null : sha1Sum.toLowerCase(), - false, file.getContentType()); - } catch (final IOException e) { - LOG.error("Failed to store artifact", e); - return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); - } - } else { + if (file.isEmpty()) { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } + String fileName = optionalFileName; - return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponse(result), HttpStatus.CREATED); + if (fileName == null) { + fileName = file.getOriginalFilename(); + } + try { + final Artifact result = artifactManagement.createLocalArtifact(file.getInputStream(), softwareModuleId, + fileName, md5Sum == null ? null : md5Sum.toLowerCase(), + sha1Sum == null ? null : sha1Sum.toLowerCase(), false, file.getContentType()); + return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponse(result), HttpStatus.CREATED); + } catch (final IOException e) { + LOG.error("Failed to store artifact", e); + return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); + } } @Override diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java new file mode 100644 index 000000000..e37786e19 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.exception; + +import org.eclipse.hawkbit.exception.SpServerError; +import org.eclipse.hawkbit.exception.SpServerRtException; + +/** + * Thrown if a multi part exception occurred. + * + */ +public final class MultiPartFileUploadException extends SpServerRtException { + + private static final long serialVersionUID = 1L; + + /** + * @param cause + * for the exception + */ + public MultiPartFileUploadException(final Throwable cause) { + super(cause.getMessage(), SpServerError.SP_ARTIFACT_UPLOAD_FAILED, cause); + } + +} diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java index 31e4a3046..13e214c45 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java @@ -13,9 +13,10 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; -import org.apache.tomcat.util.http.fileupload.FileUploadBase.FileSizeLimitExceededException; +import org.apache.tomcat.util.http.fileupload.FileUploadException; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,10 +29,6 @@ import org.springframework.web.multipart.MultipartException; /** * General controller advice for exception handling. - * - * - * - * */ @ControllerAdvice public class ResponseExceptionHandler { @@ -89,14 +86,11 @@ public class ResponseExceptionHandler { @ExceptionHandler(SpServerRtException.class) public ResponseEntity handleSpServerRtExceptions(final HttpServletRequest request, final Exception ex) { - LOG.debug("Handling exception of request {}", request.getRequestURL()); - final ExceptionInfo response = new ExceptionInfo(); + logRequest(request, ex); + final ExceptionInfo response = createExceptionInfo(ex); final HttpStatus responseStatus; - response.setMessage(ex.getMessage()); - response.setExceptionClass(ex.getClass().getName()); if (ex instanceof SpServerRtException) { responseStatus = getStatusOrDefault(((SpServerRtException) ex).getError()); - response.setErrorCode(((SpServerRtException) ex).getError().getKey()); } else { responseStatus = DEFAULT_RESPONSE_STATUS; } @@ -118,11 +112,8 @@ public class ResponseExceptionHandler { @ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity handleHttpMessageNotReadableException(final HttpServletRequest request, final Exception ex) { - LOG.debug("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL()); - final ExceptionInfo response = new ExceptionInfo(); - response.setErrorCode(SpServerError.SP_REST_BODY_NOT_READABLE.getKey()); - response.setMessage(SpServerError.SP_REST_BODY_NOT_READABLE.getMessage()); - response.setExceptionClass(MessageNotReadableException.class.getName()); + logRequest(request, ex); + final ExceptionInfo response = createExceptionInfo(new MessageNotReadableException()); return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); } @@ -139,35 +130,48 @@ public class ResponseExceptionHandler { * as entity. */ @ExceptionHandler(MultipartException.class) - public ResponseEntity handleFileLimitExceededException(final HttpServletRequest request, + public ResponseEntity handleMultipartException(final HttpServletRequest request, final Exception ex) { - LOG.debug("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL()); - final ExceptionInfo response = new ExceptionInfo(); + logRequest(request, ex); - if (searchForCause(ex, FileSizeLimitExceededException.class)) { - response.setErrorCode(SpServerError.SP_ARTIFACT_UPLOAD_FILE_LIMIT_EXCEEDED.getKey()); - response.setMessage(SpServerError.SP_ARTIFACT_UPLOAD_FILE_LIMIT_EXCEEDED.getMessage()); - response.setExceptionClass(FileSizeLimitExceededException.class.getName()); - } else { - response.setErrorCode(SpServerError.SP_ARTIFACT_UPLOAD_FAILED.getKey()); - response.setMessage(SpServerError.SP_ARTIFACT_UPLOAD_FAILED.getMessage()); - response.setExceptionClass(MultipartException.class.getName()); + Throwable responseCause = ex; + + final Throwable searchForCause = searchForCause(ex, FileUploadException.class); + if (searchForCause != null) { + responseCause = searchForCause; } + final ExceptionInfo response = createExceptionInfo(new MultiPartFileUploadException(responseCause)); return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); } - private static boolean searchForCause(final Throwable t, final Class lookFor) { - if (t != null && t.getCause() != null) { - if (t.getCause().getClass().isAssignableFrom(lookFor)) { - return true; - } else { - return searchForCause(t.getCause(), lookFor); - } + private void logRequest(final HttpServletRequest request, final Exception ex) { + LOG.debug("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL()); + } + + private static Throwable searchForCause(final Throwable t, final Class lookFor) { + if (t == null || t.getCause() == null) { + return null; } - return false; + final Throwable cause = t.getCause(); + + if (cause.getClass().equals(lookFor)) { + return cause; + } + return searchForCause(cause, lookFor); + } + + private ExceptionInfo createExceptionInfo(final Exception ex) { + final ExceptionInfo response = new ExceptionInfo(); + response.setMessage(ex.getMessage()); + response.setExceptionClass(ex.getClass().getName()); + if (ex instanceof SpServerRtException) { + response.setErrorCode(((SpServerRtException) ex).getError().getKey()); + } + + return response; } } From 850b7c68282885fac15c5f56c58cc012b3f5814d Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Fri, 24 Jun 2016 17:26:57 +0200 Subject: [PATCH 56/82] fix enable save button problem when update Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 100 +++---- .../smtable/SoftwareModuleTable.java | 1 - .../CreateUpdateSoftwareTypeLayout.java | 27 +- .../hawkbit/ui/common/CommonDialogWindow.java | 281 +++++++++++------- .../CreateUpdateDistSetTypeLayout.java | 84 +++--- .../AbstractCreateUpdateTagLayout.java | 69 +++-- .../ui/layouts/CreateUpdateTypeLayout.java | 28 +- .../DistributionAddUpdateWindowLayout.java | 186 +++--------- ...eateUpdateDistributionTagLayoutWindow.java | 6 +- .../TargetAddUpdateWindowLayout.java | 135 +++------ .../CreateUpdateTargetTagLayoutWindow.java | 4 +- .../rollout/AddUpdateRolloutWindowLayout.java | 176 +++++------ .../ui/rollout/rollout/RolloutListGrid.java | 9 +- .../ui/rollout/rollout/RolloutListHeader.java | 2 +- 14 files changed, 499 insertions(+), 609 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index fb03902b1..7e3051555 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -32,8 +32,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.spring.events.EventBus; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.AbstractField; @@ -84,9 +82,15 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private CommonDialogWindow window; - private String oldDescriptionValue; + private String originalDescriptionValue; - private String oldVendorValue; + private String originalVendorValue; + + private String originalNameValue; + + private String originalVersionValue; + + private String originalComboBoxValue; private Boolean editSwModule = Boolean.FALSE; @@ -135,26 +139,31 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - nameTextField.addTextChangeListener(this::listenerNameTextFieldChanged); + nameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalNameValue)); + nameTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, nameTextField)); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); - versionTextField.addTextChangeListener(this::listenerVersionTextFieldChanged); + versionTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVersionValue)); + versionTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, versionTextField)); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.vendor"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); vendorTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VENDOR); + vendorTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVendorValue)); descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION); - addDescriptionTextChangeListener(); - addVendorTextChangeListener(); + descTextArea + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDescriptionValue)); typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); @@ -162,43 +171,40 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY); typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); - typeComboBox.addValueChangeListener(this::listenerTypeComboBoxChanged); - populateTypeNameCombo(); - - resetOldValues(); - } - - private void listenerNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, nameTextField); - } - - private void listenerVersionTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, versionTextField); - } - - private void listenerTypeComboBoxChanged(final ValueChangeEvent event) { - window.checkMandatoryComboBox(event, typeComboBox); + typeComboBox.addValueChangeListener( + event -> window.checkMandatoryEditedValue(event, typeComboBox, originalComboBoxValue)); } private void populateTypeNameCombo() { typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer( new BeanQueryFactory(SoftwareModuleTypeBeanQuery.class))); typeComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); - } - private void resetOldValues() { - oldDescriptionValue = null; - oldVendorValue = null; + private void resetComponents() { + + vendorTextField.clear(); + nameTextField.clear(); + versionTextField.clear(); + descTextArea.clear(); + typeComboBox.clear(); + + originalDescriptionValue = null; + originalVendorValue = null; + originalComboBoxValue = null; + originalNameValue = null; + originalVersionValue = null; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } private void createWindow() { + resetComponents(); + final Label madatoryStarLabel = new Label("*"); madatoryStarLabel.setStyleName("v-caption v-required-field-indicator"); madatoryStarLabel.setWidth(null); @@ -223,9 +229,9 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), null, i18n); + getMandatoryFields(formLayout), geEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); - nameTextField.focus(); + typeComboBox.focus(); } private Map getMandatoryFields(final FormLayout formLayout) { @@ -234,18 +240,20 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; } - private void addDescriptionTextChangeListener() { - descTextArea.addTextChangeListener(event -> window.setSaveButtonEnabled(hasDescriptionChanged(event))); - } - - private void addVendorTextChangeListener() { - vendorTextField.addTextChangeListener(event -> window.setSaveButtonEnabled(hasVendorChanged(event))); + private Map geEditedFields() { + final Map editedFields = new HashMap<>(); + editedFields.put(typeComboBox.getId(), Boolean.FALSE); + editedFields.put(nameTextField.getId(), Boolean.FALSE); + editedFields.put(vendorTextField.getId(), Boolean.FALSE); + editedFields.put(versionTextField.getId(), Boolean.FALSE); + editedFields.put(descTextArea.getId(), Boolean.FALSE); + return editedFields; } /** @@ -309,13 +317,13 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se : HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getVendor())); descTextArea.setValue(swModle.getDescription() == null ? HawkbitCommonUtil.SP_STRING_EMPTY : HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getDescription())); - oldDescriptionValue = descTextArea.getValue(); - oldVendorValue = vendorTextField.getValue(); + originalDescriptionValue = descTextArea.getValue(); + originalVendorValue = vendorTextField.getValue(); + originalComboBoxValue = swModle.getType().getName(); if (swModle.getType().isDeleted()) { typeComboBox.addItem(swModle.getType().getName()); } typeComboBox.setValue(swModle.getType().getName()); - window.setSaveButtonEnabled(Boolean.FALSE); } /** @@ -324,7 +332,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private void closeThisWindow() { window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } /** @@ -361,15 +368,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se } else { addNewBaseSoftware(); } - window.setSaveButtonEnabled(false); - } - - private boolean hasDescriptionChanged(final TextChangeEvent event) { - return !(event.getText().equals(oldDescriptionValue) && vendorTextField.getValue().equals(oldVendorValue)); - } - - private boolean hasVendorChanged(final TextChangeEvent event) { - return !(event.getText().equals(oldVendorValue) && descTextArea.getValue().equals(oldDescriptionValue)); } public FormLayout getFormLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java index 6527a37be..694399b47 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleTable.java @@ -44,7 +44,6 @@ import com.vaadin.ui.UI; /** * Header of Software module table. - * */ @SpringComponent @ViewScope diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index bfd48113d..d8b32efc4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -34,7 +34,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -92,13 +91,15 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_NAME); - tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); + tagName.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagName())); + tagName.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, tagName)); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_KEY); - typeKey.addTextChangeListener(this::typeKeyTextFieldChanged); + typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTypeKey())); + typeKey.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, typeKey)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "", @@ -106,19 +107,11 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); - tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); + tagDesc.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagDesc())); singleMultiOptionGroup(); } - private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, tagName); - } - - private void typeKeyTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, typeKey); - } - @Override protected void buildLayout() { @@ -142,7 +135,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; @@ -164,6 +157,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout } else { assignOptiongroup.setEnabled(true); } + assignOptiongroup.select(singleAssignStr); } /** @@ -195,18 +189,19 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void setTagDetails(final String targetTagSelected) { tagName.setValue(targetTagSelected); + setOriginalTagName(targetTagSelected); final SoftwareModuleType selectedTypeTag = swTypeManagementService .findSoftwareModuleTypeByName(targetTagSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); - setTagDescOriginal(selectedTypeTag.getDescription()); + setOriginalTagDesc(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); + setOriginalTypeKey(selectedTypeTag.getKey()); if (selectedTypeTag.getMaxAssignments() == Integer.MAX_VALUE) { assignOptiongroup.setValue(multiAssignStr); } else { assignOptiongroup.setValue(singleAssignStr); } - setColorPickerComponentsColor(selectedTypeTag.getColour()); } } @@ -245,7 +240,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout updateSWModuleType(existingSMTypeByName); } - window.setSaveButtonEnabled(false); + // window.setSaveButtonEnabled(false); } private void createNewSWModuleType() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 05d97a0de..7602f0a83 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -11,8 +11,10 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; +import java.util.Collections; import java.util.Map; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -22,16 +24,14 @@ import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.shared.ui.colorpicker.Color; +import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.AbstractOrderedLayout; -import com.vaadin.ui.AbstractSelect; -import com.vaadin.ui.AbstractTextField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; @@ -74,9 +74,8 @@ public class CommonDialogWindow extends Window implements Serializable { private Map requiredFields; - private final Map editedFields; + private Map editedFields; - @Autowired private final I18N i18n; /** @@ -104,41 +103,155 @@ public class CommonDialogWindow extends Window implements Serializable { this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; this.requiredFields = requiredFields; + if (requiredFields == null) { + this.requiredFields = Collections.emptyMap(); + } + this.editedFields = editedFields; + if (editedFields == null) { + this.editedFields = Collections.emptyMap(); + } this.i18n = i18n; init(); } - public void checkMandatoryTextField(final TextChangeEvent event, final AbstractTextField textfield) { - - if (StringUtils.isNotBlank(event.getText())) { - if (StringUtils.isNotBlank(textfield.getCaption())) { - requiredFields.put(textfield.getCaption(), Boolean.TRUE); - } - getRequiredFields().put(textfield.getId(), Boolean.TRUE); - } else { - if (StringUtils.isNotBlank(textfield.getCaption())) { - requiredFields.put(textfield.getCaption(), Boolean.FALSE); - } - requiredFields.put(textfield.getId(), Boolean.FALSE); + /** + * Checks if all mandatory fields are filled, and if there are changes in + * the current field. If yes, the save button will be enabled. + * + * @param event + * TextChangeEvent + * @param originalValue + * original Value of the current field + */ + public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { + final Component component = event.getComponent(); + if (!(component instanceof AbstractComponent)) { + throw new IllegalStateException("Only AbstractComponent not allow"); } - checkMandatoryFieldsFilled(); + + if (requiredFields.containsKey(component.getId())) { + final boolean isTextChangeNotEmpty = StringUtils.isNotBlank(event.getText()); + setRequiredFieldChangeValue((AbstractComponent) component, isTextChangeNotEmpty); + } + checkChanges(component.getId(), event.getText(), originalValue); + checkSaveButtonEnabled(); } - public void checkMandatoryComboBox(final ValueChangeEvent event, final AbstractSelect select) { - - if (event.getProperty().getValue() != null) { - if (StringUtils.isNotBlank(select.getCaption())) { - requiredFields.put(select.getCaption(), Boolean.TRUE); - } - requiredFields.put(select.getId(), Boolean.TRUE); - } else { - if (StringUtils.isNotBlank(select.getCaption())) { - requiredFields.put(select.getCaption(), Boolean.FALSE); - } - requiredFields.put(select.getId(), Boolean.FALSE); + /** + * Checks if all mandatory fields are filled, and if there are changes in + * the current field. If yes, the save button will be enabled. + * + * @param event + * ValueChangeEvent + * @param component + * current Component + * @param originalValue + * original Value of the current field + */ + public void checkMandatoryEditedValue(final ValueChangeEvent event, final AbstractComponent component, + final String originalValue) { + final boolean isChangedValueNotNull = event.getProperty().getValue() != null; + if (requiredFields.containsKey(component.getId())) { + setRequiredFieldChangeValue(component, isChangedValueNotNull); } - checkMandatoryFieldsFilled(); + if (event.getProperty().getValue() != null) { + checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); + } else { + checkChanges(component.getId(), null, originalValue); + } + checkSaveButtonEnabled(); + } + + /** + * Checks if all mandatory fields are filled, and if there are changes in + * the current field. (Boolean) If yes, the save button will be enabled. + * + * @param event + * ValueChangeEvent + * @param component + * current Component + * @param originalValue + * original Boolean Value of the current field + */ + public void checkMandatoryEditedValueBoolean(final ValueChangeEvent event, final AbstractComponent component, + final Boolean originalValue) { + final boolean isChangedValueNotNull = event.getProperty().getValue() != null; + if (requiredFields.containsKey(component.getId())) { + setRequiredFieldChangeValue(component, isChangedValueNotNull); + } + final Boolean changed = (Boolean) event.getProperty().getValue(); + editedFields.put(component.getId(), BooleanUtils.compare(changed, originalValue) != 0); + checkSaveButtonEnabled(); + } + + /** + * Updates the map of required fields if a value is set. (e.g. on Update + * when editing a component) + * + * @param event + * ValueChangeEvent + * @param component + * current Component + */ + public void setRequiredFieldWhenUpdate(final ValueChangeEvent event, final AbstractComponent component) { + final boolean isChangedValueNotNull = event.getProperty().getValue() != null; + setRequiredFieldChangeValue(component, isChangedValueNotNull); + } + + /** + * * Updates the map of required fields if a value is set. (e.g. on Update + * when editing a component) + * + * @param fieldId + * Id of the current component + * @param filled + * Boolean if field is filled + */ + public void updateRequiredFields(final String fieldId, final Boolean filled) { + + requiredFields.put(fieldId, filled); + checkSaveButtonEnabled(); + } + + /** + * Checks if Color is changed + * + * @param fieldId + * Id of the current component + * @param newColor + * new Color + * @param oldColor + * old Color + */ + public void checkColorChange(final String fieldId, final Color newColor, final Color oldColor) { + editedFields.put(fieldId, !newColor.equals(oldColor)); + checkSaveButtonEnabled(); + } + + /** + * Updates the map of fields which can be edited. + * + * @param fieldId + * Id of the current component + * @param hasTextValueChanged + * Boolean if value has changed + */ + public void updateEditedFields(final String fieldId, final Boolean hasTextValueChanged) { + editedFields.put(fieldId, hasTextValueChanged); + checkSaveButtonEnabled(); + } + + /** + * Resets the map of mandatory and edited Fields and disable the save button + */ + public void reset() { + saveButton.setEnabled(false); + resetFields(); + } + + private void setRequiredFieldChangeValue(final AbstractComponent component, final boolean isTextChangeNotEmpty) { + requiredFields.put(component.getId(), isTextChangeNotEmpty); } /** @@ -146,69 +259,23 @@ public class CommonDialogWindow extends Window implements Serializable { * mandatory fields are filled the save button is enabled. Otherwise the * save button is disabled. */ - private void checkMandatoryFieldsFilled() { + private void checkSaveButtonEnabled() { + saveButton.setEnabled(!requiredFields.containsValue(Boolean.FALSE) && editedFields.containsValue(Boolean.TRUE)); + } + private void checkChanges(final String fieldName, final String newText, final String oldText) { + final boolean hasTextValueChanged = (StringUtils.isNotBlank(newText) && !newText.equals(oldText)) + || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText)); + editedFields.put(fieldName, hasTextValueChanged); + } + + private void resetFields() { for (final Map.Entry entry : requiredFields.entrySet()) { - if (entry.getValue() == null || entry.getValue().equals(Boolean.FALSE)) { - saveButton.setEnabled(false); - return; - } + entry.setValue(Boolean.FALSE); } - saveButton.setEnabled(true); - } - private void checkExistsChanges() { - - if (editedFields == null) { - return; - } for (final Map.Entry entry : editedFields.entrySet()) { - if (entry.getValue() != null && entry.getValue().equals(Boolean.TRUE)) { - saveButton.setEnabled(true); - return; - } - } - saveButton.setEnabled(false); - } - - public void updateRequiredFields(final String fieldId, final Boolean filled) { - - requiredFields.put(fieldId, filled); - checkMandatoryFieldsFilled(); - } - - public void checkChanges(final String fieldName, final String newText, final String oldText) { - - if ((StringUtils.isNotBlank(newText) && !newText.equals(oldText)) - || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText))) { - editedFields.put(fieldName, Boolean.TRUE); - } else { - editedFields.put(fieldName, Boolean.FALSE); - } - checkExistsChanges(); - } - - public void checkColorChange(final String fieldName, final Color newColor, final Color oldColor) { - - if (newColor.equals(oldColor)) { - editedFields.put(fieldName, Boolean.FALSE); - } else { - editedFields.put(fieldName, Boolean.TRUE); - } - checkExistsChanges(); - } - - public void resetMandatoryAndEditedFields() { - resetFields(requiredFields); - resetFields(editedFields); - } - - private void resetFields(final Map fields) { - // Reset mandatory fields are filled marker / fields are edited marker - if (fields != null) { - for (final Map.Entry entry : fields.entrySet()) { - entry.setValue(null); - } + entry.setValue(Boolean.FALSE); } } @@ -258,20 +325,22 @@ public class CommonDialogWindow extends Window implements Serializable { private void createMandatoryLabel() { - if (existsMandatoryFieldsInWindowContent()) { - final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field")); - mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); - - if (content instanceof TargetAddUpdateWindowLayout) { - ((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel); - } else if (content instanceof SoftwareModuleAddUpdateWindow) { - ((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel); - } else if (content instanceof AbstractCreateUpdateTagLayout) { - ((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel); - } - - mainLayout.addComponent(mandatoryLabel); + if (!existsMandatoryFieldsInWindowContent()) { + return; } + + final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field")); + mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY); + + if (content instanceof TargetAddUpdateWindowLayout) { + ((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof SoftwareModuleAddUpdateWindow) { + ((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel); + } else if (content instanceof AbstractCreateUpdateTagLayout) { + ((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel); + } + + mainLayout.addComponent(mandatoryLabel); } private void createCancelButton() { @@ -292,18 +361,14 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setSizeUndefined(); saveButton.addStyleName("default-color"); saveButton.addClickListener(saveButtonClickListener); - saveButton.setEnabled(!existsMandatoryFieldsInWindowContent()); + saveButton.setEnabled(false); buttonsLayout.addComponent(saveButton); buttonsLayout.setComponentAlignment(saveButton, Alignment.MIDDLE_RIGHT); buttonsLayout.setExpandRatio(saveButton, 1.0F); } private boolean existsMandatoryFieldsInWindowContent() { - - if (requiredFields != null && requiredFields.size() > 0) { - return true; - } - return false; + return !requiredFields.isEmpty(); } private void addHelpLink() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 303ca1bb2..9c6486200 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -14,7 +14,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; @@ -41,7 +40,6 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.util.IndexedContainer; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -93,6 +91,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private IndexedContainer originalSelectedTableContainer; + private String originalTypeKey; + @Override protected void createRequiredComponents() { @@ -102,13 +102,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_NAME); - tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); + tagName.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagName())); + tagName.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, tagName)); typeKey = SPUIComponentProvider.getTextField(i18n.get("textfield.key"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); - typeKey.addTextChangeListener(this::listenerTypeKeyTextFieldChanged); + typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTypeKey)); + typeKey.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, typeKey)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "", @@ -116,16 +118,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); - tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); - } - - private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { - - window.checkMandatoryTextField(event, tagName); - } - - private void listenerTypeKeyTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, typeKey); + tagDesc.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTagDesc())); } @Override @@ -279,14 +272,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addTargetTableData(id); } - if (optiongroup.getValue().equals(updateTypeStr)) { - updateMandatoryFields(); - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); - } else { - if (!selectedTableContainer.getItemIds().isEmpty()) { - window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); - } - } + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } } @@ -298,19 +284,20 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addSourceTableData(id); selectedTable.removeItem(id); - if (optiongroup.getValue().equals(updateTypeStr)) { - updateMandatoryFields(); - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); - } + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } } } private Boolean hasContentChanged() { + if (originalSelectedTableContainer == null) { + originalSelectedTableContainer = new IndexedContainer(); + } for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { final long itemId = (Long) itemIterator.next(); if (!originalSelectedTableContainer.containsId(itemId)) { + window.updateEditedFields(selectedTable.getId(), Boolean.TRUE); return Boolean.TRUE; } } @@ -319,23 +306,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout .hasNext();) { final long itemId = (Long) itemIterator.next(); if (selectedTableContainer.size() > 0 && !selectedTableContainer.containsId(itemId)) { + window.updateEditedFields(selectedTable.getId(), Boolean.TRUE); return Boolean.TRUE; } } + if (selectedTableContainer.size() > 0) { + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); + } return Boolean.FALSE; } - private void updateMandatoryFields() { - - if (StringUtils.isNotBlank(tagName.getValue())) { - window.getRequiredFields().put("Name", Boolean.TRUE); - } - if (StringUtils.isNotBlank(typeKey.getValue())) { - window.getRequiredFields().put("Key", Boolean.TRUE); - } - } - @SuppressWarnings("unchecked") private void getSourceTableData() { @@ -543,6 +524,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { + window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); selectedTable.getContainerDataSource().removeAllItems(); getSourceTableData(); distTypeSelectLayout.setEnabled(false); @@ -600,14 +582,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout protected void setTagDetails(final String distSetTypeSelected) { tagName.setValue(distSetTypeSelected); + setOriginalTagName(distSetTypeSelected); getSourceTableData(); selectedTable.getContainerDataSource().removeAllItems(); final DistributionSetType selectedTypeTag = fetchDistributionSetType(distSetTypeSelected); if (null != selectedTypeTag) { tagDesc.setValue(selectedTypeTag.getDescription()); - setTagDescOriginal(selectedTypeTag.getDescription()); + setOriginalTagDesc(selectedTypeTag.getDescription()); typeKey.setValue(selectedTypeTag.getKey()); - setTypeKeyOriginal(selectedTypeTag.getKey()); + setOriginalTypeKey(selectedTypeTag.getKey()); if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) { distTypeSelectLayout.setEnabled(true); selectedTable.setEnabled(true); @@ -669,7 +652,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } else { updateDistributionSetType(existingDistTypeByKey); } - window.setSaveButtonEnabled(false); } } @@ -687,14 +669,24 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } // Selected SoftwareModulesType - requiredFields.put(selectedTable.getId(), null); + requiredFields.put(selectedTable.getId(), Boolean.FALSE); return requiredFields; } + @Override + protected Map getEditedFields() { + final Map changeMap = new HashMap<>(); + changeMap.put(tagName.getId(), Boolean.FALSE); + changeMap.put(colorPickerLayout.getId(), Boolean.FALSE); + changeMap.put(tagDesc.getId(), Boolean.FALSE); + changeMap.put(selectedTable.getId(), Boolean.FALSE); + return changeMap; + } + @Override protected void previewButtonClicked() { if (!tagPreviewBtnClicked) { @@ -729,4 +721,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } + @Override + public String getOriginalTypeKey() { + return originalTypeKey; + } + + @Override + public void setOriginalTypeKey(final String originalTypeKey) { + this.originalTypeKey = originalTypeKey; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 195d173ed..6beb7d5b7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -36,7 +36,6 @@ import org.vaadin.spring.events.EventBus; import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.ui.AbstractField; @@ -110,8 +109,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected String tagNameValue; protected String tagDescValue; - protected Color selectedColorOriginal; - private String tagDescOriginal; + private Color originalSelectedColor; + private String originalTagDesc; + private String originalTagName; protected void createWindow() { reset(); @@ -126,7 +126,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), null); } } return requiredFields; @@ -134,8 +134,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected Map getEditedFields() { final Map changeMap = new HashMap<>(); - changeMap.put(tagDesc.getCaption(), Boolean.FALSE); + changeMap.put(tagName.getId(), Boolean.FALSE); changeMap.put(colorPickerLayout.getId(), Boolean.FALSE); + changeMap.put(tagDesc.getId(), Boolean.FALSE); return changeMap; } @@ -192,7 +193,8 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_NAME, true, "", i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); tagName.setId(SPUIDefinitions.NEW_TARGET_TAG_NAME); - tagName.addTextChangeListener(this::listenerTagNameTextFieldChanged); + tagName.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTagName)); + tagName.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, tagName)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"), @@ -200,7 +202,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC); tagDesc.setImmediate(true); tagDesc.setNullRepresentation(""); - tagDesc.addTextChangeListener(this::listenerTagDescTextAreaChanged); + tagDesc.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTagDesc)); tagNameComboBox = SPUIComponentProvider.getComboBox(null, "", "", null, null, false, "", i18n.get("label.combobox.tag")); @@ -214,16 +216,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagColorPreviewBtn.setStyleName(TAG_DYNAMIC_STYLE); } - private void listenerTagNameTextFieldChanged(final TextChangeEvent event) { - - window.checkMandatoryTextField(event, tagName); - } - - protected void listenerTagDescTextAreaChanged(final TextChangeEvent event) { - - window.checkChanges(tagDesc.getCaption(), event.getText(), tagDescOriginal); - } - protected void buildLayout() { mainLayout = new GridLayout(3, 2); @@ -352,7 +344,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } - window.setSaveButtonEnabled(false); + window.reset(); // close the color picker layout tagPreviewBtnClicked = false; // reset the selected color - Set default color @@ -383,7 +375,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagPreviewBtnClicked = false; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -474,13 +466,12 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), originalSelectedColor); } protected void closeWindow() { window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } /** @@ -687,23 +678,39 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } public Color getSelectedColorOriginal() { - return selectedColorOriginal; + return originalSelectedColor; } public void setSelectedColorOriginal(final Color selectedColorOriginal) { - this.selectedColorOriginal = selectedColorOriginal; - } - - public String getTagDescOriginal() { - return tagDescOriginal; - } - - public void setTagDescOriginal(final String tagDescOriginal) { - this.tagDescOriginal = tagDescOriginal; + this.originalSelectedColor = selectedColorOriginal; } public GridLayout getMainLayout() { return mainLayout; } + public Color getOriginalSelectedColor() { + return originalSelectedColor; + } + + public void setOriginalSelectedColor(final Color originalSelectedColor) { + this.originalSelectedColor = originalSelectedColor; + } + + public String getOriginalTagDesc() { + return originalTagDesc; + } + + public void setOriginalTagDesc(final String originalTagDesc) { + this.originalTagDesc = originalTagDesc; + } + + public String getOriginalTagName() { + return originalTagName; + } + + public void setOriginalTagName(final String originalTagName) { + this.originalTagName = originalTagName; + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index ea77d885b..556347e4f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -33,10 +33,8 @@ import com.vaadin.ui.components.colorpicker.ColorSelector; import com.vaadin.ui.themes.ValoTheme; /** - * * Superclass defining common properties and methods for creating/updating * types. - * */ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { @@ -45,7 +43,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected String createTypeStr; protected String updateTypeStr; protected TextField typeKey; - protected String typeKeyOriginal; + protected String originalTypeKey; public static final String TYPE_NAME_DYNAMIC_STYLE = "new-tag-name"; private static final String TYPE_DESC_DYNAMIC_STYLE = "new-tag-desc"; @@ -152,14 +150,13 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { } else { typeKey.setEnabled(true); tagName.setEnabled(true); - window.setSaveButtonEnabled(true); tagName.clear(); tagDesc.clear(); typeKey.clear(); comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } - window.setSaveButtonEnabled(false); + window.reset(); restoreComponentStyles(); getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR); getColorPickerLayout().getSelPreview() @@ -186,7 +183,8 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } - window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), selectedColorOriginal); + window.checkColorChange(colorPickerLayout.getId(), colorPickerLayout.getSelectedColor(), + getOriginalSelectedColor()); } /** @@ -324,22 +322,12 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { // is implemented in the inherited class } - @Override - public Color getSelectedColorOriginal() { - return selectedColorOriginal; + public String getOriginalTypeKey() { + return originalTypeKey; } - @Override - public void setSelectedColorOriginal(final Color selectedColorOriginal) { - this.selectedColorOriginal = selectedColorOriginal; - } - - public String getTypeKeyOriginal() { - return typeKeyOriginal; - } - - public void setTypeKeyOriginal(final String typeKeyOriginal) { - this.typeKeyOriginal = typeKeyOriginal; + public void setOriginalTypeKey(final String originalTypeKey) { + this.originalTypeKey = originalTypeKey; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 03dce184c..90dd8a6a6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -8,10 +8,8 @@ */ package org.eclipse.hawkbit.ui.management.dstable; -import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; -import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; @@ -44,10 +42,6 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition; import org.vaadin.spring.events.EventBus; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.event.FieldEvents.TextChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.AbstractField; @@ -62,8 +56,7 @@ import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** - * - * + * WindowContent for adding/editing a Distribution */ @SpringComponent @ViewScope @@ -104,12 +97,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private String originalDistDescription; private Boolean originalReqMigStep; private String originalDistSetType; - private final List changedComponents = new ArrayList<>(); - private ValueChangeListener reqMigStepCheckboxListerner; - private TextChangeListener descTextAreaListener; - private TextChangeListener distNameTextFieldListener; - private TextChangeListener distVersionTextFieldListener; - private ValueChangeListener distsetTypeNameComboBoxListener; private FormLayout formLayout; @@ -139,7 +126,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { formLayout.addComponent(reqMigStepCheckbox); setCompositionRoot(formLayout); - distNameTextField.focus(); } @@ -151,43 +137,42 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distNameTextField.setId(SPUIComponentIdProvider.DIST_ADD_NAME); distNameTextField.setNullRepresentation(""); - distNameTextField.addTextChangeListener(this::listenerDistNameTextFieldChanged); + distNameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDistName)); + distNameTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, distNameTextField)); distVersionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); distVersionTextField.setId(SPUIComponentIdProvider.DIST_ADD_VERSION); distVersionTextField.setNullRepresentation(""); - distVersionTextField.addTextChangeListener(this::listenerDistVersionTextFieldChanged); + distVersionTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDistVersion)); + distVersionTextField + .addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, distVersionTextField)); distsetTypeNameComboBox = SPUIComponentProvider.getComboBox(i18n.get("label.combobox.type"), "", "", null, "", false, "", i18n.get("label.combobox.type")); distsetTypeNameComboBox.setImmediate(true); distsetTypeNameComboBox.setNullSelectionAllowed(false); distsetTypeNameComboBox.setId(SPUIComponentIdProvider.DIST_ADD_DISTSETTYPE); + populateDistSetTypeNameCombo(); + distsetTypeNameComboBox.addValueChangeListener( + event -> window.checkMandatoryEditedValue(event, distsetTypeNameComboBox, originalDistSetType)); descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC); descTextArea.setNullRepresentation(""); + descTextArea + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDistDescription)); reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"), "dist-checkbox-style", null, false, ""); reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL); reqMigStepCheckbox.setId(SPUIComponentIdProvider.DIST_ADD_MIGRATION_CHECK); - } - - private void listenerDistNameTextFieldChanged(final TextChangeEvent event) { - if (!editDistribution) { - window.checkMandatoryTextField(event, distNameTextField); - } - } - - private void listenerDistVersionTextFieldChanged(final TextChangeEvent event) { - if (!editDistribution) { - window.checkMandatoryTextField(event, distVersionTextField); - } + reqMigStepCheckbox.addValueChangeListener( + event -> window.checkMandatoryEditedValueBoolean(event, reqMigStepCheckbox, originalReqMigStep)); } /** @@ -209,26 +194,17 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { return disttypeContainer; } - private void enableSaveButton() { - window.setSaveButtonEnabled(true); - } - private DistributionSetType getDefaultDistributionSetType() { final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); return tenantMetaData.getDefaultDsType(); } - private void disableSaveButton() { - window.setSaveButtonEnabled(false); - } - private void saveDistribution() { if (editDistribution) { updateDistribution(); } else { addNewDistribution(); } - window.setSaveButtonEnabled(false); } /** @@ -262,19 +238,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } - private void addListeners() { - reqMigStepCheckboxListerner = event -> checkValueChanged(originalReqMigStep, event); - descTextAreaListener = event -> checkValueChanged(originalDistDescription, event); - distNameTextFieldListener = event -> checkValueChanged(originalDistName, event); - distVersionTextFieldListener = event -> checkValueChanged(originalDistVersion, event); - distsetTypeNameComboBoxListener = event -> checkValueChanged(originalDistSetType, event); - reqMigStepCheckbox.addValueChangeListener(reqMigStepCheckboxListerner); - descTextArea.addTextChangeListener(descTextAreaListener); - distNameTextField.addTextChangeListener(distNameTextFieldListener); - distVersionTextField.addTextChangeListener(distVersionTextFieldListener); - distsetTypeNameComboBox.addValueChangeListener(distsetTypeNameComboBoxListener); - } - /** * Add new Distribution set. */ @@ -308,7 +271,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private void closeThisWindow() { window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } /** @@ -381,7 +343,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { if (distSetTypeName == null) { distsetTypeNameComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); } - notificationMessage.displayValidationError(i18n.get("message.mandatory.check")); return false; } @@ -391,7 +352,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private void discardDistribution() { /* Just close this window */ - distsetTypeNameComboBox.removeValueChangeListener(distsetTypeNameComboBoxListener); closeThisWindow(); } @@ -407,14 +367,15 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); descTextArea.clear(); reqMigStepCheckbox.clear(); - if (window != null) { - window.setSaveButtonEnabled(true); - } - removeListeners(); - changedComponents.clear(); + + originalDistDescription = null; + originalDistName = null; + originalDistSetType = null; + originalDistVersion = null; + originalReqMigStep = Boolean.FALSE; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -422,71 +383,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { populateDistSetTypeNameCombo(); } - private void removeListeners() { - reqMigStepCheckbox.removeValueChangeListener(reqMigStepCheckboxListerner); - descTextArea.removeTextChangeListener(descTextAreaListener); - distNameTextField.removeTextChangeListener(distNameTextFieldListener); - distVersionTextField.removeTextChangeListener(distVersionTextFieldListener); - } - - public void setOriginalDistName(final String originalDistName) { - this.originalDistName = originalDistName; - } - - public void setOriginalDistVersion(final String originalDistVersion) { - this.originalDistVersion = originalDistVersion; - } - - public void setOriginalDistDescription(final String originalDistDescription) { - this.originalDistDescription = originalDistDescription; - } - - private void checkValueChanged(final String originalValue, final TextChangeEvent event) { - if (editDistribution) { - final String newValue = event.getText(); - if (!originalValue.equalsIgnoreCase(newValue)) { - changedComponents.add(event.getComponent()); - } else { - changedComponents.remove(event.getComponent()); - } - enableDisableSaveButton(); - } - } - - private void checkValueChanged(final Boolean originalValue, final ValueChangeEvent event) { - if (editDistribution) { - if (!originalValue.equals(event.getProperty().getValue())) { - changedComponents.add(reqMigStepCheckbox); - } else { - changedComponents.remove(reqMigStepCheckbox); - } - enableDisableSaveButton(); - } - } - - private void checkValueChanged(final String originalValue, final ValueChangeEvent event) { - if (editDistribution) { - if (!originalValue.equals(event.getProperty().getValue())) { - changedComponents.add(distsetTypeNameComboBox); - } else { - changedComponents.remove(distsetTypeNameComboBox); - } - enableDisableSaveButton(); - } - } - - private void enableDisableSaveButton() { - if (changedComponents.isEmpty()) { - disableSaveButton(); - } else { - enableSaveButton(); - } - } - - private void setOriginalReqMigStep(final Boolean originalReqMigStep) { - this.originalReqMigStep = originalReqMigStep; - } - /** * populate data. * @@ -495,7 +391,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { public void populateValuesOfDistribution(final Long editDistId) { this.editDistId = editDistId; editDistribution = Boolean.TRUE; - window.setSaveButtonEnabled(false); final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); if (distSet != null) { distNameTextField.setValue(distSet.getName()); @@ -508,23 +403,24 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { if (distSet.getDescription() != null) { descTextArea.setValue(distSet.getDescription()); } - setOriginalDistName(distSet.getName()); - setOriginalDistVersion(distSet.getVersion()); - setOriginalDistDescription(distSet.getDescription()); - setOriginalReqMigStep(distSet.isRequiredMigrationStep()); - setOriginalDistSetTYpe(distSet.getType().getName()); - addListeners(); + originalDistName = distSet.getName(); + originalDistVersion = distSet.getVersion(); + originalDistDescription = distSet.getDescription(); + originalReqMigStep = distSet.isRequiredMigrationStep(); + originalDistSetType = distSet.getType().getName(); + window.updateEditedFields(distsetTypeNameComboBox.getId(), Boolean.FALSE); + window.updateEditedFields(reqMigStepCheckbox.getId(), Boolean.FALSE); } } public CommonDialogWindow getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); - populateRequiredComponents(); - resetComponents(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields(), null, i18n); + null, getMandatoryFields(), getEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); + populateRequiredComponents(); + resetComponents(); return window; } @@ -534,12 +430,22 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; } + private Map getEditedFields() { + final Map editedFields = new HashMap<>(); + editedFields.put(distsetTypeNameComboBox.getId(), Boolean.FALSE); + editedFields.put(distNameTextField.getId(), Boolean.FALSE); + editedFields.put(distVersionTextField.getId(), Boolean.FALSE); + editedFields.put(descTextArea.getId(), Boolean.FALSE); + editedFields.put(reqMigStepCheckbox.getId(), Boolean.FALSE); + return editedFields; + } + /** * Populate DistributionSet Type name combo. */ @@ -549,12 +455,4 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distsetTypeNameComboBox.setValue(getDefaultDistributionSetType().getName()); } - /** - * @param originalDistSetTYpe - * the originalDistSetTYpe to set - */ - public void setOriginalDistSetTYpe(final String originalDistSetType) { - this.originalDistSetType = originalDistSetType; - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 3bee67345..0bcee9d09 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -32,9 +32,7 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.UI; /** - * * Class for Create/Update Tag Layout of distribution set - * */ @SpringComponent @ViewScope @@ -98,7 +96,6 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat updateExistingTag(existingDistTag); } } - window.setSaveButtonEnabled(false); } /** @@ -157,10 +154,11 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat @Override public void setTagDetails(final String distTagSelected) { tagName.setValue(distTagSelected); + setOriginalTagName(distTagSelected); final DistributionSetTag selectedDistTag = tagManagement.findDistributionSetTag(distTagSelected); if (null != selectedDistTag) { tagDesc.setValue(selectedDistTag.getDescription()); - setTagDescOriginal(selectedDistTag.getDescription()); + setOriginalTagDesc(selectedDistTag.getDescription()); if (null == selectedDistTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 07360ed70..6c2193adb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -14,7 +14,6 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.Target; @@ -35,15 +34,12 @@ import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; -import com.vaadin.event.FieldEvents.TextChangeEvent; -import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; import com.vaadin.ui.AbstractField; import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; -import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; @@ -57,7 +53,7 @@ import com.vaadin.ui.themes.ValoTheme; @VaadinSessionScope public class TargetAddUpdateWindowLayout extends CustomComponent { private static final long serialVersionUID = -6659290471705262389L; - + @Autowired private I18N i18n; @@ -69,10 +65,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { @Autowired private transient UINotification uINotification; - + @Autowired private transient EntityFactory entityFactory; - + private TextField controllerIDTextField; private TextField nameTextField; private TextArea descTextArea; @@ -81,47 +77,47 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private FormLayout formLayout; private CommonDialogWindow window; - private String oldTargetName; - private String oldTargetDesc; - + private String originalTargetName; + private String originalTargetDesc; + private String originalControllerId; + /** * Initialize the Add Update Window Component for Target. */ public void init() { - /* create components */ createRequiredComponents(); - /* display components in layout */ buildLayout(); - /* register all listeners related to the Window */ - addListeners(); setCompositionRoot(formLayout); } private void createRequiredComponents() { /* Textfield for controller Id */ - controllerIDTextField = SPUIComponentProvider.getTextField( i18n.get("prompt.target.id"), "", ValoTheme.TEXTFIELD_TINY, true, null, - i18n.get("prompt.target.id"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); + controllerIDTextField = SPUIComponentProvider.getTextField(i18n.get("prompt.target.id"), "", + ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true, + SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID); - controllerIDTextField.addTextChangeListener(this::listenerControllerIDTextFieldChanged); + controllerIDTextField + .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalControllerId)); + controllerIDTextField + .addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, controllerIDTextField)); /* Textfield for target name */ - nameTextField = SPUIComponentProvider.getTextField( i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, false, null, - i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); + nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, + false, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.TARGET_ADD_NAME); + nameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTargetName)); /* Textarea for target description */ - descTextArea = SPUIComponentProvider.getTextArea( i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTFIELD_TINY, false, null, - i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); + descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", + ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.description"), + SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC); descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); - } - - private void listenerControllerIDTextFieldChanged(final TextChangeEvent event) { - window.checkMandatoryTextField(event, controllerIDTextField); + descTextArea.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTargetDesc)); } private void buildLayout() { - + /* * The main layout of the window contains mandatory info, textboxes * (controller Id, name & description) and action buttons layout @@ -131,56 +127,10 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { formLayout.addComponent(controllerIDTextField); formLayout.addComponent(nameTextField); formLayout.addComponent(descTextArea); - + controllerIDTextField.focus(); } - private void addListeners() { - - addTargetNameChangeListner(); - addTargetDescChangeListner(); - } - - private void addTargetNameChangeListner() { - nameTextField.addTextChangeListener(new TextChangeListener() { - - /** - * - */ - private static final long serialVersionUID = 1761855781481115921L; - - @Override - public void textChange(final TextChangeEvent event) { - if (event.getText().equals(oldTargetName) && descTextArea.getValue().equals(oldTargetDesc)) { - window.setSaveButtonEnabled(false); - } else { - window.setSaveButtonEnabled(true); - } - - } - }); - } - - private void addTargetDescChangeListner() { - descTextArea.addTextChangeListener(new TextChangeListener() { - - /** - * - */ - private static final long serialVersionUID = 5770734934988115068L; - - @Override - public void textChange(final TextChangeEvent event) { - if (event.getText().equals(oldTargetDesc) && nameTextField.getValue().equals(oldTargetName)) { - window.setSaveButtonEnabled(false); - } else { - window.setSaveButtonEnabled(true); - } - - } - }); - } - /** * Update the Target if modified. */ @@ -210,7 +160,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } else { addNewTarget(); } - window.setSaveButtonEnabled(false); } private void discardTargetListner() { @@ -244,37 +193,49 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null, getMandatoryFields(), null, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), + event -> discardTargetListner(), null, getMandatoryFields(), getEditedFields(), i18n); return window; } - + private Map getMandatoryFields() { final Map requiredFields = new HashMap<>(); final Iterator iterate = formLayout.iterator(); while (iterate.hasNext()) { final Component c = iterate.next(); if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getCaption(), null); + requiredFields.put(c.getId(), Boolean.FALSE); } } return requiredFields; } - + + private Map getEditedFields() { + final Map editedFields = new HashMap<>(); + editedFields.put(controllerIDTextField.getId(), Boolean.FALSE); + editedFields.put(nameTextField.getId(), Boolean.FALSE); + editedFields.put(descTextArea.getId(), Boolean.FALSE); + return editedFields; + } + /** * clear all fields of Target Edit Window. */ public void resetComponents() { nameTextField.clear(); nameTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - controllerIDTextField.setEnabled(true); - controllerIDTextField.setReadOnly(false); + controllerIDTextField.setEnabled(Boolean.TRUE); controllerIDTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); controllerIDTextField.clear(); descTextArea.clear(); editTarget = Boolean.FALSE; + originalControllerId = null; + originalTargetDesc = null; + originalTargetName = null; + if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -282,7 +243,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { editTarget = Boolean.FALSE; window.close(); UI.getCurrent().removeWindow(window); - window.setSaveButtonEnabled(false); } private void setTargetValues(final Target target, final String name, final String description) { @@ -303,7 +263,8 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private boolean duplicateCheck(final String newControlllerId) { final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); if (existingTarget != null) { - uINotification.displayValidationError(i18n.get("message.target.duplicate.check", new Object[] {newControlllerId})); + uINotification.displayValidationError( + i18n.get("message.target.duplicate.check", new Object[] { newControlllerId })); return false; } else { return true; @@ -319,15 +280,15 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { editTarget = Boolean.TRUE; final Target target = targetManagement.findTargetByControllerID(controllerId); controllerIDTextField.setValue(target.getControllerId()); - controllerIDTextField.setReadOnly(Boolean.TRUE); + controllerIDTextField.setEnabled(Boolean.FALSE); nameTextField.setValue(target.getName()); if (target.getDescription() != null) { descTextArea.setValue(target.getDescription()); } - window.setSaveButtonEnabled(Boolean.FALSE); - oldTargetDesc = descTextArea.getValue(); - oldTargetName = nameTextField.getValue(); + originalTargetDesc = descTextArea.getValue(); + originalTargetName = nameTextField.getValue(); + originalControllerId = controllerIDTextField.getValue(); window.addStyleName("target-update-window"); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index 81c0c72ae..781e13ef6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -88,10 +88,11 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa @Override public void setTagDetails(final String targetTagSelected) { tagName.setValue(targetTagSelected); + setOriginalTagName(targetTagSelected); final TargetTag selectedTargetTag = tagManagement.findTargetTag(targetTagSelected); if (null != selectedTargetTag) { tagDesc.setValue(selectedTargetTag.getDescription()); - setTagDescOriginal(selectedTargetTag.getDescription()); + setOriginalTagDesc(selectedTargetTag.getDescription()); if (null == selectedTargetTag.getColour()) { setTagColor(getColorPickerLayout().getDefaultColor(), ColorPickerConstants.DEFAULT_COLOR); setSelectedColorOriginal(getColorPickerLayout().getDefaultColor()); @@ -115,7 +116,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa updateExistingTag(existingTag); } } - window.setSaveButtonEnabled(false); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index c1efa9f4b..18e06814a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -75,9 +75,7 @@ import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** - * * Rollout add or update popup layout. - * */ @SpringComponent @ViewScope @@ -150,19 +148,21 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; - private Boolean updateMode = Boolean.FALSE; + private String originalDistributionSet; - private String distributionSetOriginal; + private Object originalActionGroup; - private Object actionGroupOriginal; + private String originalRolloutName; - private String rolloutNameOriginal; + private String originalErrorThreshold; - private String errorThresholdOriginal;; + private String originalTriggerThreshold; - private String triggerThresholdOriginal; + private String originalDescription; - private String descriptionOriginal; + private String originalTargetFilterQueryCombo; + + private String originalNoOfGroups; /** * Create components and layout. @@ -174,6 +174,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } public CommonDialogWindow getWindow() { + window = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), uiProperties.getLinks().getDocumentation().getRolloutView(), getMandatoryFields(), getEditedFields(), @@ -181,25 +182,14 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return window; } - public CommonDialogWindow createUpdateWindow() { - updateMode = Boolean.TRUE; - return getWindow(); - } - - public CommonDialogWindow createAddWindow() { - updateMode = Boolean.FALSE; - return getWindow(); - } - private Map getMandatoryFields() { final Map requiredFields = new HashMap<>(); - requiredFields.put(rolloutName.getId(), null); - requiredFields.put(distributionSet.getId(), null); - requiredFields.put(targetFilterQueryCombo.getId(), null); - requiredFields.put(noOfGroups.getId(), null); - requiredFields.put(triggerThreshold.getId(), null); - requiredFields.put(errorThreshold.getId(), null); - + requiredFields.put(rolloutName.getId(), Boolean.FALSE); + requiredFields.put(distributionSet.getId(), Boolean.FALSE); + requiredFields.put(targetFilterQueryCombo.getId(), Boolean.FALSE); + requiredFields.put(noOfGroups.getId(), Boolean.FALSE); + requiredFields.put(triggerThreshold.getId(), Boolean.FALSE); + requiredFields.put(errorThreshold.getId(), Boolean.FALSE); return requiredFields; } @@ -224,7 +214,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { rolloutForEdit = null; if (window != null) { - window.resetMandatoryAndEditedFields(); + window.reset(); } } @@ -319,13 +309,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private void listenerActionGroupValueChanged(final ValueChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryComboBox(event, actionTypeOptionGroupLayout.getActionTypeOptionGroup()); - } - if (event.getProperty().getValue() != null) { - window.checkChanges(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), - event.getProperty().getValue().toString(), actionGroupOriginal.toString()); - } + window.checkMandatoryEditedValue(event, actionTypeOptionGroupLayout.getActionTypeOptionGroup(), + originalActionGroup.toString()); } } @@ -346,9 +331,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { filterField.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY); filterField.setEnabled(false); filterField.setSizeUndefined(); + filterField.addValueChangeListener(event -> listenerFilterFieldValueChanged(event, filterField)); return filterField; } + private void listenerFilterFieldValueChanged(final ValueChangeEvent event, final TextArea filterField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, targetFilterQueryCombo); + } + } + private Label createTotalTargetsLabel() { final Label targetCountLabel = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); targetCountLabel.addStyleName(ValoTheme.LABEL_TINY + " " + "rollout-target-count-message"); @@ -404,9 +396,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsCount = 0L; totalTargetsLabel.setVisible(false); } - onGroupNumberChange(); - - window.checkMandatoryComboBox(event, targetFilterQueryCombo); + onGroupNumberChange(event); + window.setRequiredFieldWhenUpdate(event, targetFilterQueryCombo); + window.checkMandatoryEditedValue(event, targetFilterQueryCombo, originalTargetFilterQueryCombo); } private String getTotalTargetMessage() { @@ -618,11 +610,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private void listenerDescriptionTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, description); - return; - } - window.checkChanges(description.getId(), event.getText(), descriptionOriginal); + window.checkMandatoryEditedTextField(event, originalDescription); } } @@ -633,16 +621,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { errorField.setMaxLength(7); errorField.setSizeUndefined(); errorField.addTextChangeListener(this::listenerErrorThresholdTextFieldChanged); + errorField.addValueChangeListener(event -> listenerErrorThresholdValueChanged(event, errorField)); return errorField; } private void listenerErrorThresholdTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, errorThreshold); - return; - } - window.checkChanges(errorThreshold.getId(), event.getText(), errorThresholdOriginal); + window.checkMandatoryEditedTextField(event, originalErrorThreshold); + } + } + + private void listenerErrorThresholdValueChanged(final ValueChangeEvent event, final TextField errorField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, errorField); } } @@ -653,16 +644,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { thresholdField.setSizeUndefined(); thresholdField.setMaxLength(3); thresholdField.addTextChangeListener(this::listenerTriggerThresholdTextFieldChanged); + thresholdField.addValueChangeListener(event -> listenerTriggerTresholdValueChanged(event, thresholdField)); return thresholdField; } + private void listenerTriggerTresholdValueChanged(final ValueChangeEvent event, final TextField thresholdField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, thresholdField); + } + } + private void listenerTriggerThresholdTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, triggerThreshold); - return; - } - window.checkChanges(triggerThreshold.getId(), event.getText(), triggerThresholdOriginal); + window.checkMandatoryEditedTextField(event, originalTriggerThreshold); } } @@ -672,28 +666,27 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroupsField.addValidator(new GroupNumberValidator()); noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); - noOfGroupsField.addValueChangeListener(evevt -> onGroupNumberChange()); + noOfGroupsField.addValueChangeListener(this::onGroupNumberChange); noOfGroupsField.addTextChangeListener(this::listenerNoOfGroupsTextFieldChanged); return noOfGroupsField; } private void listenerNoOfGroupsTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, noOfGroups); - return; - } - window.checkChanges(noOfGroups.getId(), event.getText(), noOfGroups.getValue()); + window.checkMandatoryEditedTextField(event, originalNoOfGroups); } } - private void onGroupNumberChange() { + private void onGroupNumberChange(final ValueChangeEvent event) { if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) { groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize()))); groupSizeLabel.setVisible(true); } else { groupSizeLabel.setVisible(false); } + if (window != null) { + window.setRequiredFieldWhenUpdate(event, noOfGroups); + } } private ComboBox createDistributionSetCombo() { @@ -710,14 +703,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private void listenerDistributionSetChanged(final ValueChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryComboBox(event, distributionSet); - return; - } - if (event.getProperty().getValue() != null) { - window.checkChanges(distributionSet.getId(), event.getProperty().getValue().toString(), - distributionSetOriginal); - } + window.checkMandatoryEditedValue(event, distributionSet, originalDistributionSet); } } @@ -732,7 +718,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return new LazyQueryContainer( new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_DIST_ID_NAME), distributionQF); - } private TextField createRolloutNameField() { @@ -740,16 +725,19 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { rolloutNameField.setId(SPUIComponentIdProvider.ROLLOUT_NAME_FIELD_ID); rolloutNameField.setSizeUndefined(); rolloutNameField.addTextChangeListener(this::listenerRolloutNameTextFieldChanged); + rolloutNameField.addValueChangeListener(event -> listenerRolloutNameValueChanged(event, rolloutNameField)); return rolloutNameField; } private void listenerRolloutNameTextFieldChanged(final TextChangeEvent event) { if (window != null) { - if (!updateMode) { - window.checkMandatoryTextField(event, rolloutName); - return; - } - window.checkChanges(rolloutName.getId(), event.getText(), rolloutNameOriginal); + window.checkMandatoryEditedTextField(event, originalRolloutName); + } + } + + private void listenerRolloutNameValueChanged(final ValueChangeEvent event, final TextField rolloutNameField) { + if (window != null) { + window.setRequiredFieldWhenUpdate(event, rolloutNameField); } } @@ -851,7 +839,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { description.setValue(rolloutForEdit.getDescription()); distributionSet.setValue(DistributionSetIdName.generate(rolloutForEdit.getDistributionSet())); final List rolloutGroups = rolloutForEdit.getRolloutGroups(); - setThresoldValues(rolloutGroups); + setThresholdValues(rolloutGroups); setActionType(rolloutForEdit); if (rolloutForEdit.getStatus() != RolloutStatus.READY) { disableRequiredFieldsOnEdit(); @@ -870,30 +858,28 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void setOriginalValues() { - distributionSetOriginal = distributionSet.getValue().toString(); - actionGroupOriginal = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); - rolloutNameOriginal = rolloutName.getValue(); - triggerThresholdOriginal = triggerThreshold.getValue(); - errorThresholdOriginal = errorThreshold.getValue(); - descriptionOriginal = description.getValue(); + originalDistributionSet = distributionSet.getValue().toString(); + originalActionGroup = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); + originalRolloutName = rolloutName.getValue(); + originalTriggerThreshold = triggerThreshold.getValue(); + originalErrorThreshold = errorThreshold.getValue(); + originalDescription = description.getValue(); + originalNoOfGroups = noOfGroups.getValue(); + if (targetFilterQueryCombo.getValue() != null) { + originalTargetFilterQueryCombo = targetFilterQueryCombo.getValue().toString(); + } } private Map getEditedFields() { final Map changeMap = new HashMap<>(); - if (rolloutForEdit == null) { - return changeMap; - } - if (rolloutForEdit.getStatus() != RolloutStatus.READY) { - changeMap.put(rolloutName.getId(), Boolean.FALSE); - changeMap.put(description.getId(), Boolean.FALSE); - } else { - changeMap.put(rolloutName.getId(), Boolean.FALSE); - changeMap.put(distributionSet.getId(), Boolean.FALSE); - changeMap.put(triggerThreshold.getId(), Boolean.FALSE); - changeMap.put(errorThreshold.getId(), Boolean.FALSE); - changeMap.put(description.getId(), Boolean.FALSE); - changeMap.put(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), Boolean.FALSE); - } + changeMap.put(rolloutName.getId(), Boolean.FALSE); + changeMap.put(distributionSet.getId(), Boolean.FALSE); + changeMap.put(targetFilterQueryCombo.getId(), Boolean.FALSE); + changeMap.put(noOfGroups.getId(), Boolean.FALSE); + changeMap.put(triggerThreshold.getId(), Boolean.FALSE); + changeMap.put(errorThreshold.getId(), Boolean.FALSE); + changeMap.put(description.getId(), Boolean.FALSE); + changeMap.put(actionTypeOptionGroupLayout.getActionTypeOptionGroup().getId(), Boolean.FALSE); return changeMap; } @@ -933,7 +919,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { /** * @param rolloutGroups */ - private void setThresoldValues(final List rolloutGroups) { + private void setThresholdValues(final List rolloutGroups) { if (null != rolloutGroups && !rolloutGroups.isEmpty()) { errorThreshold.setValue(rolloutGroups.get(0).getErrorConditionExp()); triggerThreshold.setValue(rolloutGroups.get(0).getSuccessConditionExp()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index d3b17da5f..b40c3d93d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -67,9 +67,7 @@ import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent; import com.vaadin.ui.renderers.HtmlRenderer; /** - * * Rollout list grid component. - * */ @SpringComponent @ViewScope @@ -159,7 +157,6 @@ public class RolloutListGrid extends AbstractGrid { } item.getItemProperty(ROLLOUT_RENDERER_DATA) .setValue(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString())); - } @Override @@ -200,7 +197,6 @@ public class RolloutListGrid extends AbstractGrid { rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.ACTION, String.class, FontAwesome.CIRCLE_O.getHtml(), false, false); - } @Override @@ -292,7 +288,6 @@ public class RolloutListGrid extends AbstractGrid { for (final Object propertyId : columnsToBeHidden) { getColumn(propertyId).setHidden(true); } - } @Override @@ -315,7 +310,6 @@ public class RolloutListGrid extends AbstractGrid { final RolloutRenderer customObjectRenderer = new RolloutRenderer(RolloutRendererData.class); customObjectRenderer.addClickListener(this::onClickOfRolloutName); getColumn(ROLLOUT_RENDERER_DATA).setRenderer(customObjectRenderer); - } private void createRolloutStatusToFontMap() { @@ -437,8 +431,8 @@ public class RolloutListGrid extends AbstractGrid { } private void onUpdate(final ContextMenuData contextMenuData) { + final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(); addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId()); - final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.createUpdateWindow(); addTargetWindow.setCaption(i18n.get("caption.update.rollout")); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); @@ -684,7 +678,6 @@ public class RolloutListGrid extends AbstractGrid { public Class getPresentationType() { return String.class; } - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 22c57740f..1a3d2d7a5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -92,7 +92,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { addUpdateRolloutWindow.resetComponents(); - final Window addTargetWindow = addUpdateRolloutWindow.createAddWindow(); + final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); From a5ee3018209cff815299f67679453cf182230368 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Sat, 25 Jun 2016 12:29:12 +0200 Subject: [PATCH 57/82] update javadoc Signed-off-by: Michael Hirsch --- .../main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index ae25d0086..538f82213 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -145,7 +145,7 @@ public class AmqpConfiguration { } /** - * Create the DMF API receiver queue for + * Create the DMF API receiver queue for retrieving DMF messages. * * @return the receiver queue */ From 8578f6726b24f6f8b309a9453b55f680a2700c19 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 27 Jun 2016 11:20:57 +0200 Subject: [PATCH 58/82] Return last throwable in response Signed-off-by: SirWayne --- .../exception/ResponseExceptionHandler.java | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java index 13e214c45..3a6250209 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java @@ -9,17 +9,20 @@ package org.eclipse.hawkbit.rest.exception; import java.util.EnumMap; +import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; -import org.apache.tomcat.util.http.fileupload.FileUploadException; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerRtException; import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ResourceLoader; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -27,6 +30,8 @@ import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.multipart.MultipartException; +import com.google.common.collect.Iterables; + /** * General controller advice for exception handling. */ @@ -37,6 +42,9 @@ public class ResponseExceptionHandler { private static final Map ERROR_TO_HTTP_STATUS = new EnumMap<>(SpServerError.class); private static final HttpStatus DEFAULT_RESPONSE_STATUS = HttpStatus.INTERNAL_SERVER_ERROR; + @Autowired + private ResourceLoader resourceLoader; + static { ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_NOT_EXISTS, HttpStatus.NOT_FOUND); ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_ALRREADY_EXISTS, HttpStatus.CONFLICT); @@ -135,13 +143,8 @@ public class ResponseExceptionHandler { logRequest(request, ex); - Throwable responseCause = ex; - - final Throwable searchForCause = searchForCause(ex, FileUploadException.class); - if (searchForCause != null) { - responseCause = searchForCause; - } - + final List throwables = ExceptionUtils.getThrowableList(ex); + final Throwable responseCause = Iterables.getLast(throwables); final ExceptionInfo response = createExceptionInfo(new MultiPartFileUploadException(responseCause)); return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); } @@ -150,19 +153,6 @@ public class ResponseExceptionHandler { LOG.debug("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL()); } - private static Throwable searchForCause(final Throwable t, final Class lookFor) { - if (t == null || t.getCause() == null) { - return null; - } - - final Throwable cause = t.getCause(); - - if (cause.getClass().equals(lookFor)) { - return cause; - } - return searchForCause(cause, lookFor); - } - private ExceptionInfo createExceptionInfo(final Exception ex) { final ExceptionInfo response = new ExceptionInfo(); response.setMessage(ex.getMessage()); From c4fcdea0e0290ab4c7f857a557334b3df007bb7e Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 27 Jun 2016 12:24:29 +0200 Subject: [PATCH 59/82] Remove resouce loader Signed-off-by: SirWayne --- .../hawkbit/rest/exception/ResponseExceptionHandler.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java index 3a6250209..02a48ef78 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java @@ -21,8 +21,6 @@ import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.ResourceLoader; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageNotReadableException; @@ -42,9 +40,6 @@ public class ResponseExceptionHandler { private static final Map ERROR_TO_HTTP_STATUS = new EnumMap<>(SpServerError.class); private static final HttpStatus DEFAULT_RESPONSE_STATUS = HttpStatus.INTERNAL_SERVER_ERROR; - @Autowired - private ResourceLoader resourceLoader; - static { ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_NOT_EXISTS, HttpStatus.NOT_FOUND); ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_ENTITY_ALRREADY_EXISTS, HttpStatus.CONFLICT); From 6692f92c61558146a78039eea2e2521e13a6bcf3 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 27 Jun 2016 12:33:07 +0200 Subject: [PATCH 60/82] delete unused method Signed-off-by: Melanie Retter --- .../CreateUpdateSoftwareTypeLayout.java | 7 ------- .../hawkbit/ui/common/CommonDialogWindow.java | 3 +-- .../CreateUpdateDistSetTypeLayout.java | 21 ++++++++----------- .../ui/layouts/CreateUpdateTypeLayout.java | 20 ------------------ ...eateUpdateDistributionTagLayoutWindow.java | 15 ++++++------- .../CreateUpdateTargetTagLayoutWindow.java | 14 ++++++------- 6 files changed, 22 insertions(+), 58 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index d8b32efc4..0c47772ea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -223,11 +223,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout @Override protected void save(final ClickEvent event) { - if (!mandatoryValuesPresent()) { - window.setSaveButtonEnabled(false); - return; - } - final SoftwareModuleType existingSMTypeByKey = swTypeManagementService .findSoftwareModuleTypeByKey(typeKey.getValue()); final SoftwareModuleType existingSMTypeByName = swTypeManagementService @@ -237,10 +232,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout createNewSWModuleType(); } } else { - updateSWModuleType(existingSMTypeByName); } - // window.setSaveButtonEnabled(false); } private void createNewSWModuleType() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 7602f0a83..f6ff9e553 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -127,7 +127,7 @@ public class CommonDialogWindow extends Window implements Serializable { public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { final Component component = event.getComponent(); if (!(component instanceof AbstractComponent)) { - throw new IllegalStateException("Only AbstractComponent not allow"); + throw new IllegalStateException("Only AbstractComponent are allowed"); } if (requiredFields.containsKey(component.getId())) { @@ -209,7 +209,6 @@ public class CommonDialogWindow extends Window implements Serializable { * Boolean if field is filled */ public void updateRequiredFields(final String fieldId, final Boolean filled) { - requiredFields.put(fieldId, filled); checkSaveButtonEnabled(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 9c6486200..4a566cb51 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -639,19 +639,16 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @Override protected void save(final ClickEvent event) { - - if (mandatoryValuesPresent()) { - final DistributionSetType existingDistTypeByKey = distributionSetManagement - .findDistributionSetTypeByKey(typeKey.getValue()); - final DistributionSetType existingDistTypeByName = distributionSetManagement - .findDistributionSetTypeByName(tagName.getValue()); - if (optiongroup.getValue().equals(createTypeStr)) { - if (!checkIsDuplicateByKey(existingDistTypeByKey) && !checkIsDuplicate(existingDistTypeByName)) { - createNewDistributionSetType(); - } - } else { - updateDistributionSetType(existingDistTypeByKey); + final DistributionSetType existingDistTypeByKey = distributionSetManagement + .findDistributionSetTypeByKey(typeKey.getValue()); + final DistributionSetType existingDistTypeByName = distributionSetManagement + .findDistributionSetTypeByName(tagName.getValue()); + if (optiongroup.getValue().equals(createTypeStr)) { + if (!checkIsDuplicateByKey(existingDistTypeByKey) && !checkIsDuplicate(existingDistTypeByName)) { + createNewDistributionSetType(); } + } else { + updateDistributionSetType(existingDistTypeByKey); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 556347e4f..6ede668b0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -17,9 +17,7 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; @@ -289,24 +287,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { return Boolean.FALSE; } - @Override - protected Boolean mandatoryValuesPresent() { - if (Strings.isNullOrEmpty(tagName.getValue()) || Strings.isNullOrEmpty(typeKey.getValue())) { - if (optiongroup.getValue().equals(createTypeStr)) { - displayValidationError(SPUILabelDefinitions.MISSING_TYPE_NAME_KEY); - } - if (optiongroup.getValue().equals(updateTypeStr)) { - if (null == tagNameComboBox.getValue()) { - displayValidationError(i18n.get("message.error.missing.tagName")); - } else { - displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME); - } - } - return Boolean.FALSE; - } - return Boolean.TRUE; - } - @Override protected void save(final ClickEvent event) { // is implemented in the inherited class diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java index 0bcee9d09..1522c19c3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java @@ -85,16 +85,13 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat */ @Override public void save(final ClickEvent event) { - if (mandatoryValuesPresent()) { - final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue()); - if (optiongroup.getValue().equals(createTagStr)) { - if (!checkIsDuplicate(existingDistTag)) { - createNewTag(); - } - } else { - - updateExistingTag(existingDistTag); + final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue()); + if (optiongroup.getValue().equals(createTagStr)) { + if (!checkIsDuplicate(existingDistTag)) { + createNewTag(); } + } else { + updateExistingTag(existingDistTag); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index 781e13ef6..8bba7f2f2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -106,15 +106,13 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa @Override public void save(final ClickEvent event) { - if (mandatoryValuesPresent()) { - final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue()); - if (optiongroup.getValue().equals(createTagStr)) { - if (!checkIsDuplicate(existingTag)) { - createNewTag(); - } - } else { - updateExistingTag(existingTag); + final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue()); + if (optiongroup.getValue().equals(createTagStr)) { + if (!checkIsDuplicate(existingTag)) { + createNewTag(); } + } else { + updateExistingTag(existingTag); } } From 1436aae22a63100fca3f7cfb094e5d110b4cf6b8 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 27 Jun 2016 15:56:50 +0200 Subject: [PATCH 61/82] code review improvements Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 18 +--- .../CreateUpdateSoftwareTypeLayout.java | 22 +---- .../hawkbit/ui/common/CommonDialogWindow.java | 16 +--- .../CreateUpdateDistSetTypeLayout.java | 90 +++++++++---------- .../AbstractCreateUpdateTagLayout.java | 26 ++---- .../ui/layouts/CreateUpdateTypeLayout.java | 2 +- .../DistributionAddUpdateWindowLayout.java | 18 +--- .../TargetAddUpdateWindowLayout.java | 19 +--- .../ui/utils/CommonDialogWindowHelper.java | 32 +++++++ 9 files changed, 95 insertions(+), 148 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 7e3051555..140760bbb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import java.io.Serializable; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import org.eclipse.hawkbit.repository.EntityFactory; @@ -21,6 +20,7 @@ import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -34,9 +34,7 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; @@ -229,23 +227,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), geEditedFields(), i18n); + CommonDialogWindowHelper.getMandatoryFields(formLayout), geEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); typeComboBox.focus(); } - private Map getMandatoryFields(final FormLayout formLayout) { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } - private Map geEditedFields() { final Map editedFields = new HashMap<>(); editedFields.put(typeComboBox.getId(), Boolean.FALSE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 0c47772ea..71581113d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -9,10 +9,7 @@ package org.eclipse.hawkbit.ui.artifacts.smtype; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; -import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; @@ -25,6 +22,7 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -37,10 +35,8 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Component; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.components.colorpicker.ColorChangeListener; @@ -125,20 +121,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout public void createWindow() { reset(); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, getMandatoryFields(), - getEditedFields(), i18n); - } - - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = getFormLayout().iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, + CommonDialogWindowHelper.getMandatoryFields(getFormLayout()), getEditedFields(), i18n); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index f6ff9e553..d80446ee8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -127,7 +127,7 @@ public class CommonDialogWindow extends Window implements Serializable { public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { final Component component = event.getComponent(); if (!(component instanceof AbstractComponent)) { - throw new IllegalStateException("Only AbstractComponent are allowed"); + throw new IllegalStateException("Only AbstractComponents are allowed"); } if (requiredFields.containsKey(component.getId())) { @@ -155,10 +155,10 @@ public class CommonDialogWindow extends Window implements Serializable { if (requiredFields.containsKey(component.getId())) { setRequiredFieldChangeValue(component, isChangedValueNotNull); } - if (event.getProperty().getValue() != null) { - checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); - } else { + if (event.getProperty().getValue() == null) { checkChanges(component.getId(), null, originalValue); + } else { + checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); } checkSaveButtonEnabled(); } @@ -392,12 +392,4 @@ public class CommonDialogWindow extends Window implements Serializable { return buttonsLayout; } - public Map getRequiredFields() { - return requiredFields; - } - - public void setRequiredFields(final Map requiredFields) { - this.requiredFields = requiredFields; - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 4a566cb51..7c06493e5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -27,6 +27,7 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -43,7 +44,6 @@ import com.vaadin.data.util.IndexedContainer; import com.vaadin.server.FontAwesome; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.AbstractSelect.ItemDescriptionGenerator; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; @@ -91,8 +91,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private IndexedContainer originalSelectedTableContainer; - private String originalTypeKey; - @Override protected void createRequiredComponents() { @@ -109,7 +107,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_KEY, true, "", i18n.get("textfield.key"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); typeKey.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_KEY); - typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalTypeKey)); + typeKey.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, getOriginalTypeKey())); typeKey.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, typeKey)); tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "", @@ -268,24 +266,26 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout private void addSMType() { final Set selectedIds = (Set) sourceTable.getValue(); - if (selectedIds != null && !selectedIds.isEmpty()) { - for (final Long id : selectedIds) { - addTargetTableData(id); - } - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); + if (selectedIds == null) { + return; } + for (final Long id : selectedIds) { + addTargetTableData(id); + } + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } private void removeSMType() { @SuppressWarnings("unchecked") final Set selectedIds = (Set) selectedTable.getValue(); - if (selectedIds != null && !selectedIds.isEmpty()) { - for (final Long id : selectedIds) { - addSourceTableData(id); - selectedTable.removeItem(id); - window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); - } + if (selectedIds == null) { + return; + } + for (final Long id : selectedIds) { + addSourceTableData(id); + selectedTable.removeItem(id); + window.updateRequiredFields(selectedTable.getId(), hasContentChanged()); } } @@ -294,6 +294,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout if (originalSelectedTableContainer == null) { originalSelectedTableContainer = new IndexedContainer(); } + // is new softwareModule added? for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { final long itemId = (Long) itemIterator.next(); if (!originalSelectedTableContainer.containsId(itemId)) { @@ -302,6 +303,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } } + // is softwareModule removed and at least one softwareModule is selected for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator .hasNext();) { final long itemId = (Long) itemIterator.next(); @@ -311,9 +313,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout } } - if (selectedTableContainer.size() > 0) { - window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); - } return Boolean.FALSE; } @@ -621,20 +620,20 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout @SuppressWarnings("unchecked") private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) { - Item saveTblitem; - if (selectedTableContainer != null) { - saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); - sourceTable.removeItem(swModuleType.getId()); - saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); - final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer - .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); - mandatoryCheckbox.addValueChangeListener(this::listenerMandatoryCheckboxChanged); - - final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); - originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + if (selectedTableContainer == null) { + return; } + final Item saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); + sourceTable.removeItem(swModuleType.getId()); + saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); + saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer + .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); + mandatoryCheckbox.addValueChangeListener(this::listenerMandatoryCheckboxChanged); + + final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); + originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); + originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); } @Override @@ -660,15 +659,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout getEditedFields(), i18n); } - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = getFormLayout().iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } + protected Map getMandatoryFields() { + final Map requiredFields = CommonDialogWindowHelper.getMandatoryFields(getFormLayout()); // Selected SoftwareModulesType requiredFields.put(selectedTable.getId(), Boolean.FALSE); return requiredFields; @@ -718,14 +710,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } - @Override - public String getOriginalTypeKey() { - return originalTypeKey; - } - - @Override - public void setOriginalTypeKey(final String originalTypeKey) { - this.originalTypeKey = originalTypeKey; - } + // @Override + // public String getOriginalTypeKey() { + // return originalTypeKey; + // } + // + // @Override + // public void setOriginalTypeKey(final String originalTypeKey) { + // this.originalTypeKey = originalTypeKey; + // } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 6beb7d5b7..5eb64773b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -9,7 +9,6 @@ package org.eclipse.hawkbit.ui.layouts; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import javax.annotation.PreDestroy; @@ -24,6 +23,7 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -38,11 +38,9 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.server.Page; import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; @@ -115,21 +113,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent protected void createWindow() { reset(); - setWindow( - SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, - this, this::save, this::discard, null, getMandatoryFields(), getEditedFields(), i18n)); - } - - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), null); - } - } - return requiredFields; + setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null, + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null, + CommonDialogWindowHelper.getMandatoryFields(formLayout), getEditedFields(), i18n)); } protected Map getEditedFields() { @@ -344,7 +330,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(comboLabel); comboLayout.removeComponent(tagNameComboBox); } - window.reset(); + if (window != null) { + window.reset(); + } // close the color picker layout tagPreviewBtnClicked = false; // reset the selected color - Set default color diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 6ede668b0..e03e6b42d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -41,7 +41,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout { protected String createTypeStr; protected String updateTypeStr; protected TextField typeKey; - protected String originalTypeKey; + private String originalTypeKey; public static final String TYPE_NAME_DYNAMIC_STYLE = "new-tag-name"; private static final String TYPE_DESC_DYNAMIC_STYLE = "new-tag-desc"; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 90dd8a6a6..b733dbe58 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -9,7 +9,6 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; import javax.annotation.PostConstruct; @@ -27,6 +26,7 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.DragEvent; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -44,10 +44,8 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.AbstractField; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; @@ -417,25 +415,13 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, getMandatoryFields(), getEditedFields(), i18n); + null, CommonDialogWindowHelper.getMandatoryFields(formLayout), getEditedFields(), i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); populateRequiredComponents(); resetComponents(); return window; } - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } - private Map getEditedFields() { final Map editedFields = new HashMap<>(); editedFields.put(distsetTypeNameComboBox.getId(), Boolean.FALSE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 6c2193adb..7cf047d5e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.management.targettable; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; import java.util.Set; @@ -23,6 +22,7 @@ import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.management.event.DragEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; +import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -36,8 +36,6 @@ import org.vaadin.spring.events.EventBus; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.VaadinSessionScope; -import com.vaadin.ui.AbstractField; -import com.vaadin.ui.Component; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; @@ -194,22 +192,11 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), - event -> discardTargetListner(), null, getMandatoryFields(), getEditedFields(), i18n); + event -> discardTargetListner(), null, CommonDialogWindowHelper.getMandatoryFields(formLayout), + getEditedFields(), i18n); return window; } - private Map getMandatoryFields() { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } - private Map getEditedFields() { final Map editedFields = new HashMap<>(); editedFields.put(controllerIDTextField.getId(), Boolean.FALSE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java new file mode 100644 index 000000000..c906a87dd --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java @@ -0,0 +1,32 @@ +package org.eclipse.hawkbit.ui.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; + +public class CommonDialogWindowHelper { + + /** + * Run through a FormLayout and collect all required Component's IDs in a + * Map + * + * @param formLayout + * Form to be analysed + * @return Map with all required component's IDs + */ + public static Map getMandatoryFields(final FormLayout formLayout) { + final Map requiredFields = new HashMap<>(); + final Iterator iterate = formLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { + requiredFields.put(c.getId(), Boolean.FALSE); + } + } + return requiredFields; + } +} From 63cf97f6b46ea46772c43e60c0ea8e186d85c8bf Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 27 Jun 2016 17:02:44 +0200 Subject: [PATCH 62/82] Refactor Signed-off-by: SirWayne --- .../SoftwareModuleAddUpdateWindow.java | 17 +- .../hawkbit/ui/common/CommonDialogWindow.java | 305 ++++++------------ .../ui/components/SPUIComponentProvider.java | 7 +- .../ui/decorators/SPUIWindowDecorator.java | 9 +- 4 files changed, 111 insertions(+), 227 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 7e3051555..1d692b6d2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -139,31 +139,22 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); nameTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_NAME); - nameTextField.addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalNameValue)); - nameTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, nameTextField)); /* version text field */ versionTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.version"), "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("textfield.version"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); versionTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VERSION); - versionTextField - .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVersionValue)); - versionTextField.addValueChangeListener(event -> window.setRequiredFieldWhenUpdate(event, versionTextField)); /* Vendor text field */ vendorTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.vendor"), "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.vendor"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH); vendorTextField.setId(SPUIComponentIdProvider.SOFT_MODULE_VENDOR); - vendorTextField - .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalVendorValue)); descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH); descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION); - descTextArea - .addTextChangeListener(event -> window.checkMandatoryEditedTextField(event, originalDescriptionValue)); typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true, null, i18n.get("upload.swmodule.type")); @@ -172,8 +163,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setNewItemsAllowed(Boolean.FALSE); typeComboBox.setImmediate(Boolean.TRUE); populateTypeNameCombo(); - typeComboBox.addValueChangeListener( - event -> window.checkMandatoryEditedValue(event, typeComboBox, originalComboBoxValue)); } private void populateTypeNameCombo() { @@ -195,10 +184,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se originalComboBoxValue = null; originalNameValue = null; originalVersionValue = null; - - if (window != null) { - window.reset(); - } } private void createWindow() { @@ -229,7 +214,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se /* add main layout to the window */ window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - getMandatoryFields(formLayout), geEditedFields(), i18n); + formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); typeComboBox.focus(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index f6ff9e553..d920d2f58 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -11,10 +11,12 @@ package org.eclipse.hawkbit.ui.common; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; -import java.util.Collections; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.Objects; -import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -25,17 +27,17 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.event.FieldEvents.TextChangeEvent; +import com.vaadin.event.FieldEvents.TextChangeNotifier; import com.vaadin.server.FontAwesome; -import com.vaadin.shared.ui.colorpicker.Color; -import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.AbstractField; +import com.vaadin.ui.AbstractLayout; import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; @@ -45,12 +47,13 @@ import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; /** - * Superclass for pop-up-windows including a minimize and close icon in the - * upper right corner and a save and cancel button at the bottom. + * TODO: AbstractColorPicker und FlexibleOptionGroupItemComponent Superclass for + * pop-up-windows including a minimize and close icon in the upper right corner + * and a save and cancel button at the bottom. */ public class CommonDialogWindow extends Window implements Serializable { - private static final long serialVersionUID = -1321949234316858703L; + private static final long serialVersionUID = 1L; private final VerticalLayout mainLayout = new VerticalLayout(); @@ -72,9 +75,9 @@ public class CommonDialogWindow extends Window implements Serializable { private final ClickListener cancelButtonClickListener; - private Map requiredFields; + private Map orginalValues; - private Map editedFields; + private final List> allComponents; private final I18N i18n; @@ -94,7 +97,7 @@ public class CommonDialogWindow extends Window implements Serializable { */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, - final Map requiredFields, final Map editedFields, final I18N i18n) { + final FormLayout formLayout, final I18N i18n) { checkNotNull(saveButtonClickListener); checkNotNull(cancelButtonClickListener); this.caption = caption; @@ -102,180 +105,21 @@ public class CommonDialogWindow extends Window implements Serializable { this.helpLink = helpLink; this.saveButtonClickListener = saveButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener; - this.requiredFields = requiredFields; - if (requiredFields == null) { - this.requiredFields = Collections.emptyMap(); - } - - this.editedFields = editedFields; - if (editedFields == null) { - this.editedFields = Collections.emptyMap(); - } + this.allComponents = getAllComponents(formLayout); this.i18n = i18n; init(); } - /** - * Checks if all mandatory fields are filled, and if there are changes in - * the current field. If yes, the save button will be enabled. - * - * @param event - * TextChangeEvent - * @param originalValue - * original Value of the current field - */ - public void checkMandatoryEditedTextField(final TextChangeEvent event, final String originalValue) { - final Component component = event.getComponent(); - if (!(component instanceof AbstractComponent)) { - throw new IllegalStateException("Only AbstractComponent are allowed"); - } - - if (requiredFields.containsKey(component.getId())) { - final boolean isTextChangeNotEmpty = StringUtils.isNotBlank(event.getText()); - setRequiredFieldChangeValue((AbstractComponent) component, isTextChangeNotEmpty); - } - checkChanges(component.getId(), event.getText(), originalValue); - checkSaveButtonEnabled(); + public void setSaveButtonEnabled(final boolean enabled) { + saveButton.setEnabled(enabled); } - /** - * Checks if all mandatory fields are filled, and if there are changes in - * the current field. If yes, the save button will be enabled. - * - * @param event - * ValueChangeEvent - * @param component - * current Component - * @param originalValue - * original Value of the current field - */ - public void checkMandatoryEditedValue(final ValueChangeEvent event, final AbstractComponent component, - final String originalValue) { - final boolean isChangedValueNotNull = event.getProperty().getValue() != null; - if (requiredFields.containsKey(component.getId())) { - setRequiredFieldChangeValue(component, isChangedValueNotNull); - } - if (event.getProperty().getValue() != null) { - checkChanges(component.getId(), event.getProperty().getValue().toString(), originalValue); - } else { - checkChanges(component.getId(), null, originalValue); - } - checkSaveButtonEnabled(); + public void setCancelButtonEnabled(final boolean enabled) { + cancelButton.setEnabled(enabled); } - /** - * Checks if all mandatory fields are filled, and if there are changes in - * the current field. (Boolean) If yes, the save button will be enabled. - * - * @param event - * ValueChangeEvent - * @param component - * current Component - * @param originalValue - * original Boolean Value of the current field - */ - public void checkMandatoryEditedValueBoolean(final ValueChangeEvent event, final AbstractComponent component, - final Boolean originalValue) { - final boolean isChangedValueNotNull = event.getProperty().getValue() != null; - if (requiredFields.containsKey(component.getId())) { - setRequiredFieldChangeValue(component, isChangedValueNotNull); - } - final Boolean changed = (Boolean) event.getProperty().getValue(); - editedFields.put(component.getId(), BooleanUtils.compare(changed, originalValue) != 0); - checkSaveButtonEnabled(); - } - - /** - * Updates the map of required fields if a value is set. (e.g. on Update - * when editing a component) - * - * @param event - * ValueChangeEvent - * @param component - * current Component - */ - public void setRequiredFieldWhenUpdate(final ValueChangeEvent event, final AbstractComponent component) { - final boolean isChangedValueNotNull = event.getProperty().getValue() != null; - setRequiredFieldChangeValue(component, isChangedValueNotNull); - } - - /** - * * Updates the map of required fields if a value is set. (e.g. on Update - * when editing a component) - * - * @param fieldId - * Id of the current component - * @param filled - * Boolean if field is filled - */ - public void updateRequiredFields(final String fieldId, final Boolean filled) { - requiredFields.put(fieldId, filled); - checkSaveButtonEnabled(); - } - - /** - * Checks if Color is changed - * - * @param fieldId - * Id of the current component - * @param newColor - * new Color - * @param oldColor - * old Color - */ - public void checkColorChange(final String fieldId, final Color newColor, final Color oldColor) { - editedFields.put(fieldId, !newColor.equals(oldColor)); - checkSaveButtonEnabled(); - } - - /** - * Updates the map of fields which can be edited. - * - * @param fieldId - * Id of the current component - * @param hasTextValueChanged - * Boolean if value has changed - */ - public void updateEditedFields(final String fieldId, final Boolean hasTextValueChanged) { - editedFields.put(fieldId, hasTextValueChanged); - checkSaveButtonEnabled(); - } - - /** - * Resets the map of mandatory and edited Fields and disable the save button - */ - public void reset() { - saveButton.setEnabled(false); - resetFields(); - } - - private void setRequiredFieldChangeValue(final AbstractComponent component, final boolean isTextChangeNotEmpty) { - requiredFields.put(component.getId(), isTextChangeNotEmpty); - } - - /** - * Checks the mandatory fields in the pop-up-window content. If all - * mandatory fields are filled the save button is enabled. Otherwise the - * save button is disabled. - */ - private void checkSaveButtonEnabled() { - saveButton.setEnabled(!requiredFields.containsValue(Boolean.FALSE) && editedFields.containsValue(Boolean.TRUE)); - } - - private void checkChanges(final String fieldName, final String newText, final String oldText) { - final boolean hasTextValueChanged = (StringUtils.isNotBlank(newText) && !newText.equals(oldText)) - || (StringUtils.isNotBlank(oldText) && !oldText.equals(newText)); - editedFields.put(fieldName, hasTextValueChanged); - } - - private void resetFields() { - for (final Map.Entry entry : requiredFields.entrySet()) { - entry.setValue(Boolean.FALSE); - } - - for (final Map.Entry entry : editedFields.entrySet()) { - entry.setValue(Boolean.FALSE); - } + public HorizontalLayout getButtonsLayout() { + return buttonsLayout; } private final void init() { @@ -304,6 +148,85 @@ public class CommonDialogWindow extends Window implements Serializable { center(); setModal(true); addStyleName("fontsize"); + setOrginaleValues(); + addListeners(); + } + + private final void setOrginaleValues() { + for (final AbstractField field : allComponents) { + orginalValues.put(field, field.getValue()); + } + } + + private final void addListeners() { + for (final AbstractField field : allComponents) { + field.addValueChangeListener(event -> saveButton.setEnabled(isSaveButtonEnabled())); + if (field instanceof TextChangeNotifier) { + ((TextChangeNotifier) field) + .addTextChangeListener(event -> saveButton.setEnabled(isSaveButtonEnabled())); + } + } + + saveButton.addClickListener(event -> save()); + } + + private void save() { + saveButton.setEnabled(false); + setOrginaleValues(); + } + + private boolean isSaveButtonEnabled() { + return isMandatoyFieldNotEmpty() && isValuesChanged(); + } + + private boolean isValuesChanged() { + for (final AbstractField field : allComponents) { + final Object currentValue = field.getValue(); + final Object orginalValue = orginalValues.get(field); + + if (!Objects.equals(currentValue, orginalValue)) { + return true; + } + + } + return false; + } + + private boolean shouldMandatoryLabelShown() { + for (final AbstractField field : allComponents) { + if (field.isRequired()) { + return true; + } + } + + return false; + } + + private boolean isMandatoyFieldNotEmpty() { + for (final AbstractField field : allComponents) { + // TODO empty string. + if (field.isRequired() && field.getValue() == null) { + return false; + } + } + return true; + } + + private List> getAllComponents(final AbstractLayout abstractLayout) { + final List> components = new ArrayList<>(); + + final Iterator iterate = abstractLayout.iterator(); + while (iterate.hasNext()) { + final Component c = iterate.next(); + if (c instanceof AbstractLayout) { + components.addAll(getAllComponents((AbstractLayout) c)); + } + + if (c instanceof AbstractField) { + components.add((AbstractField) c); + } + } + return components; } private HorizontalLayout createActionButtonsLayout() { @@ -324,7 +247,7 @@ public class CommonDialogWindow extends Window implements Serializable { private void createMandatoryLabel() { - if (!existsMandatoryFieldsInWindowContent()) { + if (!shouldMandatoryLabelShown()) { return; } @@ -366,10 +289,6 @@ public class CommonDialogWindow extends Window implements Serializable { buttonsLayout.setExpandRatio(saveButton, 1.0F); } - private boolean existsMandatoryFieldsInWindowContent() { - return !requiredFields.isEmpty(); - } - private void addHelpLink() { if (StringUtils.isEmpty(helpLink)) { @@ -380,24 +299,4 @@ public class CommonDialogWindow extends Window implements Serializable { buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT); } - public void setSaveButtonEnabled(final boolean enabled) { - saveButton.setEnabled(enabled); - } - - public void setCancelButtonEnabled(final boolean enabled) { - cancelButton.setEnabled(enabled); - } - - public HorizontalLayout getButtonsLayout() { - return buttonsLayout; - } - - public Map getRequiredFields() { - return requiredFields; - } - - public void setRequiredFields(final Map requiredFields) { - this.requiredFields = requiredFields; - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 3338124c5..d0e509f7e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -37,6 +37,7 @@ import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Link; @@ -153,10 +154,10 @@ public final class SPUIComponentProvider { */ public static CommonDialogWindow getWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields, final I18N i18n) { + final ClickListener cancelButtonClickListener, final String helpLink, final FormLayout formLayout, + final I18N i18n) { return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener, - cancelButtonClickListener, helpLink, requiredFields, editedFields, i18n); + cancelButtonClickListener, helpLink, formLayout, i18n); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java index d2d7740d3..242d8931a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIWindowDecorator.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.ui.decorators; -import java.util.Map; - import org.eclipse.hawkbit.ui.common.CommonDialogWindow; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; @@ -17,6 +15,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.Component; +import com.vaadin.ui.FormLayout; import com.vaadin.ui.Window; /** @@ -47,11 +46,11 @@ public final class SPUIWindowDecorator { */ public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type, final Component content, final ClickListener saveButtonClickListener, - final ClickListener cancelButtonClickListener, final String helpLink, - final Map requiredFields, final Map editedFields, final I18N i18n) { + final ClickListener cancelButtonClickListener, final String helpLink, final FormLayout formLayout, + final I18N i18n) { final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener, - cancelButtonClickListener, requiredFields, editedFields, i18n); + cancelButtonClickListener, formLayout, i18n); if (null != id) { window.setId(id); } From 5defb8c6d9932389b3d8720115c52a223c269153 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 27 Jun 2016 17:52:55 +0200 Subject: [PATCH 63/82] Fixed bug where DDI deplyomentBase URL does not reflect TIMEFORCED switch. Signed-off-by: Kai Zimmermann --- .../rest/resource/DataConversionHelper.java | 24 ++++++++-- .../rest/resource/DdiDeploymentBaseTest.java | 46 ++++++++++++++++++- .../src/test/resources/logback.xml | 21 +++++++++ 3 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 hawkbit-ddi-resource/src/test/resources/logback.xml diff --git a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java index b07e2557c..d87de67d0 100644 --- a/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java +++ b/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java @@ -79,12 +79,12 @@ public final class DataConversionHelper { final org.eclipse.hawkbit.repository.model.SoftwareModule module, final ArtifactUrlHandler artifactUrlHandler) { final List files = new ArrayList<>(); - + module.getLocalArtifacts() - .forEach(artifact -> files.add(createArtifact(targetid, artifactUrlHandler, artifact))); + .forEach(artifact -> files.add(createArtifact(targetid, artifactUrlHandler, artifact))); return files; } - + private static DdiArtifact createArtifact(final String targetid, final ArtifactUrlHandler artifactUrlHandler, final LocalArtifact artifact) { final DdiArtifact file = new DdiArtifact(); @@ -125,7 +125,7 @@ public final class DataConversionHelper { // response because of eTags. result.add(linkTo(methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .getControllerBasedeploymentAction(target.getControllerId(), action.getId(), - actions.hashCode())).withRel(DdiRestConstants.DEPLOYMENT_BASE_ACTION)); + calculateEtag(action))).withRel(DdiRestConstants.DEPLOYMENT_BASE_ACTION)); addedUpdate = true; } else if (action.isCancelingOrCanceled() && !addedCancel) { result.add(linkTo(methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) @@ -142,6 +142,22 @@ public final class DataConversionHelper { return result; } + /** + * Calculates an etag for the given {@link Action} based on the entities + * hashcode and the {@link Action#isHitAutoForceTime(long)} to reflect a + * force switch. + * + * @param action + * to calculate the etag for + * @return the etag + */ + private static int calculateEtag(final Action action) { + final int prime = 31; + int result = action.hashCode(); + result = prime * result + (action.isHitAutoForceTime(System.currentTimeMillis()) ? 1231 : 1237); + return result; + } + static void writeMD5FileResponse(final String fileName, final HttpServletResponse response, final LocalArtifact artifact) throws IOException { final StringBuilder builder = new StringBuilder(); diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java index 33d470b3d..0ec0d0d7e 100644 --- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java +++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java @@ -23,15 +23,17 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.RandomUtils; +import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionStatus; -import org.eclipse.hawkbit.repository.model.RepositoryModelConstants; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.RepositoryModelConstants; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB; @@ -43,6 +45,9 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort.Direction; import org.springframework.hateoas.MediaTypes; import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; + +import com.jayway.jsonpath.JsonPath; import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; @@ -229,6 +234,45 @@ public class DdiDeploymentBaseTest extends AbstractRestIntegrationTestWithMongoD assertThat(actionStatusMessage.getStatus()).isEqualTo(Status.RETRIEVED); } + @Test + @Description("Checks that the deployementBase URL changes when the action is switched from soft to forced in TIMEFORCED case.") + public void changeEtagIfActionSwitchesFromSoftToForced() throws Exception { + // Prepare test data + final Target target = targetManagement.createTarget(entityFactory.generateTarget("4712")); + final DistributionSet ds = testdataFactory.createDistributionSet("", true); + + final DistributionSetAssignmentResult result = deploymentManagement.assignDistributionSet(ds.getId(), + ActionType.TIMEFORCED, System.currentTimeMillis() + 1_000, target.getControllerId()); + + final Action action = deploymentManagement.findActiveActionsByTarget(result.getAssignedEntity().get(0)).get(0); + + MvcResult mvcResult = mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)).andReturn(); + + final String urlBeforeSwitch = JsonPath.compile("_links.deploymentBase.href") + .read(mvcResult.getResponse().getContentAsString()).toString(); + + // Time is not yet over, so we should see the same URL + mvcResult = mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)).andReturn(); + assertThat(JsonPath.compile("_links.deploymentBase.href").read(mvcResult.getResponse().getContentAsString()) + .toString()).isEqualTo(urlBeforeSwitch) + .startsWith("http://localhost/" + tenantAware.getCurrentTenant() + + "/controller/v1/4712/deploymentBase/" + action.getId()); + + // After the time is over we should see a new etag + TimeUnit.MILLISECONDS.sleep(1_000); + + mvcResult = mvc.perform(get("/{tenant}/controller/v1/4712", tenantAware.getCurrentTenant())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)).andReturn(); + + assertThat(JsonPath.compile("_links.deploymentBase.href").read(mvcResult.getResponse().getContentAsString()) + .toString()).isNotEqualTo(urlBeforeSwitch); + } + @Test @Description("Attempt/soft deployment to a controller. Checks if the resource reponse payload for a given deployment is as expected.") public void deplomentAttemptAction() throws Exception { diff --git a/hawkbit-ddi-resource/src/test/resources/logback.xml b/hawkbit-ddi-resource/src/test/resources/logback.xml new file mode 100644 index 000000000..447712338 --- /dev/null +++ b/hawkbit-ddi-resource/src/test/resources/logback.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + \ No newline at end of file From 4fdeb1661aafcf74f1e0ecb63a09c2642c05ec62 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 15:02:36 +0200 Subject: [PATCH 64/82] Add require textfielder to rollouts and remove colorpicker Signed-off-by: SirWayne --- .../CreateUpdateSoftwareTypeLayout.java | 34 ------------- .../hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../CreateUpdateDistSetTypeLayout.java | 36 -------------- .../rollout/AddUpdateRolloutWindowLayout.java | 48 +++++++------------ 4 files changed, 18 insertions(+), 102 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 2c6dcd702..3ca0e3631 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -11,13 +11,11 @@ package org.eclipse.hawkbit.ui.artifacts.smtype; import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -34,7 +32,6 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.shared.ui.colorpicker.Color; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.Alignment; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; @@ -266,37 +263,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout } - /** - * Open color picker on click of preview button. Auto select the color based - * on target tag if already selected. - */ - @Override - protected void previewButtonClicked() { - if (!tagPreviewBtnClicked) { - final String selectedOption = (String) optiongroup.getValue(); - if (StringUtils.isNotEmpty(selectedOption) && selectedOption.equalsIgnoreCase(updateTypeStr)) { - if (null != tagNameComboBox.getValue()) { - final SoftwareModuleType typeSelected = swTypeManagementService - .findSoftwareModuleTypeByName(tagNameComboBox.getValue().toString()); - if (null != typeSelected) { - getColorPickerLayout().setSelectedColor(typeSelected.getColour() != null - ? ColorPickerHelper.rgbToColorConverter(typeSelected.getColour()) - : ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } - } else { - getColorPickerLayout().setSelectedColor( - ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } - } - getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); - mainLayout.addComponent(colorPickerLayout, 1, 0); - mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER); - } else { - mainLayout.removeComponent(colorPickerLayout); - } - tagPreviewBtnClicked = !tagPreviewBtnClicked; - } - @Override public void addColorChangeListener(final ColorChangeListener listener) { LOG.debug("inside addColorChangeListener"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index e6fb5e957..db1c8bfdb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -219,7 +219,7 @@ public class CommonDialogWindow extends Window implements Serializable { if (String.class.equals(field.getType())) { orginalValue = Strings.emptyToNull((String) orginalValue); - currentValue = Strings.emptyToNull((String) orginalValue); + currentValue = Strings.emptyToNull((String) currentValue); } if (!Objects.equals(orginalValue, currentValue)) { return true; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 6dcb1af0b..b33d7b087 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -654,33 +654,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return requiredFields; } - @Override - protected void previewButtonClicked() { - if (!tagPreviewBtnClicked) { - final String selectedOption = (String) optiongroup.getValue(); - if (null != selectedOption && selectedOption.equalsIgnoreCase(updateTypeStr) - && null != tagNameComboBox.getValue()) { - - final DistributionSetType existedDistType = distributionSetManagement - .findDistributionSetTypeByKey(tagNameComboBox.getValue().toString()); - if (null != existedDistType) { - getColorPickerLayout().setSelectedColor(existedDistType.getColour() != null - ? ColorPickerHelper.rgbToColorConverter(existedDistType.getColour()) - : ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } else { - getColorPickerLayout().setSelectedColor( - ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR)); - } - } - getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor()); - mainLayout.addComponent(colorPickerLayout, 1, 0); - mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER); - } else { - mainLayout.removeComponent(colorPickerLayout); - } - tagPreviewBtnClicked = !tagPreviewBtnClicked; - } - @Override protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { @@ -688,14 +661,5 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } - // @Override - // public String getOriginalTypeKey() { - // return originalTypeKey; - // } - // - // @Override - // public void setOriginalTypeKey(final String originalTypeKey) { - // this.originalTypeKey = originalTypeKey; - // } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 071b9c749..e03f72b1e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -146,22 +146,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; - private String originalDistributionSet; - - private Object originalActionGroup; - - private String originalRolloutName; - - private String originalErrorThreshold; - - private String originalTriggerThreshold; - - private String originalDescription; - - private String originalTargetFilterQueryCombo; - - private String originalNoOfGroups; - /** * Create components and layout. */ @@ -172,7 +156,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } public CommonDialogWindow getWindow() { - + resetComponents(); window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); @@ -222,20 +206,35 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { addComponent(getMandatoryLabel("textfield.name"), 0, 0); addComponent(rolloutName, 1, 0); + rolloutName.setRequired(true); + addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1); addComponent(distributionSet, 1, 1); + distributionSet.setRequired(true); + addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2); addComponent(targetFilterQueryCombo, 1, 2); + targetFilterQueryCombo.setRequired(true); + addComponent(totalTargetsLabel, 2, 2); + addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3); addComponent(noOfGroups, 1, 3); + noOfGroups.setRequired(true); + addComponent(groupSizeLabel, 2, 3); + addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4); addComponent(triggerThreshold, 1, 4); + triggerThreshold.setRequired(true); + addComponent(getPercentHintLabel(), 2, 4); + addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5); addComponent(errorThreshold, 1, 5); + errorThreshold.setRequired(true); addComponent(errorThresholdOptionGroup, 2, 5); + addComponent(getLabel("textfield.description"), 0, 6); addComponent(description, 1, 6, 2, 6); addComponent(actionTypeOptionGroupLayout, 0, 7, 2, 7); @@ -752,20 +751,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { totalTargetsLabel.setValue(getTotalTargetMessage()); totalTargetsLabel.setVisible(true); - setOriginalValues(); - } - - private void setOriginalValues() { - originalDistributionSet = distributionSet.getValue().toString(); - originalActionGroup = actionTypeOptionGroupLayout.getActionTypeOptionGroup().getValue(); - originalRolloutName = rolloutName.getValue(); - originalTriggerThreshold = triggerThreshold.getValue(); - originalErrorThreshold = errorThreshold.getValue(); - originalDescription = description.getValue(); - originalNoOfGroups = noOfGroups.getValue(); - if (targetFilterQueryCombo.getValue() != null) { - originalTargetFilterQueryCombo = targetFilterQueryCombo.getValue().toString(); - } + window.setOrginaleValues(); } private void disableRequiredFieldsOnEdit() { From 7723c30ce4b1186f7d0b28fae3ab068236b2e740 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 16:25:50 +0200 Subject: [PATCH 65/82] Fix window open issues and set values when a entity is selected Signed-off-by: SirWayne --- .../SoftwareModuleAddUpdateWindow.java | 40 ++++++----- .../hawkbit/ui/common/CommonDialogWindow.java | 34 ++++++++- .../CreateUpdateDistSetTypeLayout.java | 11 --- .../dstable/DistributionSetDetails.java | 3 +- .../dstable/DistributionSetTableHeader.java | 2 +- .../AbstractCreateUpdateTagLayout.java | 4 +- .../DistributionAddUpdateWindowLayout.java | 72 +++++++------------ .../dstable/DistributionDetails.java | 3 +- .../dstable/DistributionTableHeader.java | 2 +- .../ui/utils/CommonDialogWindowHelper.java | 32 --------- 10 files changed, 85 insertions(+), 118 deletions(-) delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 4c31aefec..73346454d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.artifacts.smtable; import java.io.Serializable; +import javax.annotation.PostConstruct; + import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -39,7 +41,6 @@ import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; -import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; /** @@ -84,6 +85,14 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se private FormLayout formLayout; + /** + * Initialize Distribution Add and Edit Window. + */ + @PostConstruct + void init() { + createRequiredComponents(); + } + /** * Create window for new software module. * @@ -91,11 +100,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se * module. */ public CommonDialogWindow createAddSoftwareModuleWindow() { - - editSwModule = Boolean.FALSE; - createRequiredComponents(); - createWindow(); - return window; + return createUpdateSoftwareModuleWindow(null); } /** @@ -106,15 +111,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se * @return reference of {@link com.vaadin.ui.Window} to update software * module. */ - public Window createUpdateSoftwareModuleWindow(final Long baseSwModuleId) { - - editSwModule = Boolean.TRUE; + public CommonDialogWindow createUpdateSoftwareModuleWindow(final Long baseSwModuleId) { this.baseSwModuleId = baseSwModuleId; - createRequiredComponents(); + resetComponents(); + populateValuesOfSwModule(); createWindow(); - nameTextField.setEnabled(false); - versionTextField.setEnabled(false); - typeComboBox.setEnabled(false); return window; } @@ -162,12 +163,10 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se versionTextField.clear(); descTextArea.clear(); typeComboBox.clear(); + editSwModule = Boolean.FALSE; } private void createWindow() { - - resetComponents(); - final Label madatoryStarLabel = new Label("*"); madatoryStarLabel.setStyleName("v-caption v-required-field-indicator"); madatoryStarLabel.setWidth(null); @@ -184,11 +183,15 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se setCompositionRoot(formLayout); - populateValuesOfSwModule(); window = SPUIWindowDecorator.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); + + nameTextField.setEnabled(!editSwModule); + versionTextField.setEnabled(!editSwModule); + typeComboBox.setEnabled(!editSwModule); + typeComboBox.focus(); } @@ -243,6 +246,9 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se * fill the data of a softwareModule in the content of the window */ private void populateValuesOfSwModule() { + if (baseSwModuleId == null) { + return; + } final SoftwareModule swModle = softwareManagement.findSoftwareModuleById(baseSwModuleId); nameTextField.setValue(swModle.getName()); versionTextField.setValue(swModle.getVersion()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index db1c8bfdb..888fd1409 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -31,6 +31,8 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.google.common.base.Strings; +import com.vaadin.data.Container.ItemSetChangeEvent; +import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.event.FieldEvents.TextChangeEvent; @@ -50,6 +52,7 @@ import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Link; +import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; @@ -132,6 +135,18 @@ public class CommonDialogWindow extends Window implements Serializable { for (final AbstractField field : allComponents) { removeTextListener(field); removeValueChangeListener(field); + removeItemSetChangeistener(field); + } + } + + private void removeItemSetChangeistener(final AbstractField field) { + if (!(field instanceof Table)) { + return; + } + for (final Object listener : field.getListeners(ItemSetChangeEvent.class)) { + if (listener instanceof ChangeListener) { + ((Table) field).removeItemSetChangeListener((ChangeListener) listener); + } } } @@ -186,8 +201,14 @@ public class CommonDialogWindow extends Window implements Serializable { public final void setOrginaleValues() { for (final AbstractField field : allComponents) { - orginalValues.put(field, field.getValue()); + Object value = field.getValue(); + + if (field instanceof Table) { + value = ((Table) field).getContainerDataSource().getItemIds(); + } + orginalValues.put(field, value); } + saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null)); } @@ -197,6 +218,10 @@ public class CommonDialogWindow extends Window implements Serializable { if (field instanceof TextChangeNotifier) { ((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field)); } + + if (field instanceof Table) { + ((Table) field).addItemSetChangeListener(new ChangeListener(field)); + } } saveButton.addClickListener(event -> close()); @@ -360,7 +385,7 @@ public class CommonDialogWindow extends Window implements Serializable { return this.buttonsLayout; } - private class ChangeListener implements ValueChangeListener, TextChangeListener { + private class ChangeListener implements ValueChangeListener, TextChangeListener, ItemSetChangeListener { private final Field field; @@ -380,6 +405,11 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, field.getValue())); } + @Override + public void containerItemSetChange(final ItemSetChangeEvent event) { + saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getContainer().getItemIds())); + } + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index b33d7b087..cc73e3467 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.ui.distributions.disttype; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -18,7 +17,6 @@ import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants; import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper; import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -26,7 +24,6 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent; import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; -import org.eclipse.hawkbit.ui.utils.CommonDialogWindowHelper; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -647,13 +644,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return i18n.get("caption.add.type"); } - protected Map getMandatoryFields() { - final Map requiredFields = CommonDialogWindowHelper.getMandatoryFields(getFormLayout()); - // Selected SoftwareModulesType - requiredFields.put(selectedTable.getId(), Boolean.FALSE); - return requiredFields; - } - @Override protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { @@ -661,5 +651,4 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID); } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 95441ae57..d51d4fb28 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -259,8 +259,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet @Override protected void onEdit(final ClickEvent event) { - distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId()); - final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(); + final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId()); newDistWindow.setCaption(getI18n().get("caption.update.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java index 817b465c2..8f392101f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTableHeader.java @@ -152,7 +152,7 @@ public class DistributionSetTableHeader extends AbstractTableHeader { @Override protected void addNewItem(final ClickEvent event) { - final Window newDistWindow = addUpdateWindowLayout.getWindow(); + final Window newDistWindow = addUpdateWindowLayout.getWindow(null); newDistWindow.setCaption(i18n.get("caption.add.new.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 5b3266f02..8c85f63a5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -331,6 +331,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent comboLayout.removeComponent(tagNameComboBox); // Default green color + colorPickerLayout.setVisible(false); colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; @@ -424,9 +425,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor()); } - // TODO: - // window.checkColorChange(colorPickerLayout.getId(), - // colorPickerLayout.getSelectedColor(), originalSelectedColor); } protected void closeWindow() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 939753380..3e60a20ab 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -90,11 +90,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private boolean editDistribution = Boolean.FALSE; private Long editDistId; private CommonDialogWindow window; - private String originalDistName; - private String originalDistVersion; - private String originalDistDescription; - private Boolean originalReqMigStep; - private String originalDistSetType; private FormLayout formLayout; @@ -108,11 +103,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } private void buildLayout() { - - /* - * The main layout of the window contains mandatory info, textboxes - * (controller Id, name & description) and action buttons layout - */ addStyleName("lay-color"); setSizeUndefined(); @@ -354,50 +344,38 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { descTextArea.clear(); reqMigStepCheckbox.clear(); - originalDistDescription = null; - originalDistName = null; - originalDistSetType = null; - originalDistVersion = null; - originalReqMigStep = Boolean.FALSE; - } - private void populateRequiredComponents() { + private void populateValuesOfDistribution(final Long editDistId) { + this.editDistId = editDistId; + if (editDistId == null) { + return; + } + + final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); + if (distSet == null) { + return; + } + + editDistribution = Boolean.TRUE; + distNameTextField.setValue(distSet.getName()); + distVersionTextField.setValue(distSet.getVersion()); + if (distSet.getType().isDeleted()) { + distsetTypeNameComboBox.addItem(distSet.getType().getName()); + } + distsetTypeNameComboBox.setValue(distSet.getType().getName()); + reqMigStepCheckbox.setValue(distSet.isRequiredMigrationStep()); + if (distSet.getDescription() != null) { + descTextArea.setValue(distSet.getDescription()); + } populateDistSetTypeNameCombo(); } - /** - * populate data. - * - * @param editDistId - */ - public void populateValuesOfDistribution(final Long editDistId) { - this.editDistId = editDistId; - editDistribution = Boolean.TRUE; - final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); - if (distSet != null) { - distNameTextField.setValue(distSet.getName()); - distVersionTextField.setValue(distSet.getVersion()); - if (distSet.getType().isDeleted()) { - distsetTypeNameComboBox.addItem(distSet.getType().getName()); - } - distsetTypeNameComboBox.setValue(distSet.getType().getName()); - reqMigStepCheckbox.setValue(distSet.isRequiredMigrationStep()); - if (distSet.getDescription() != null) { - descTextArea.setValue(distSet.getDescription()); - } - originalDistName = distSet.getName(); - originalDistVersion = distSet.getVersion(); - originalDistDescription = distSet.getDescription(); - originalReqMigStep = distSet.isRequiredMigrationStep(); - originalDistSetType = distSet.getType().getName(); - } - } - - public CommonDialogWindow getWindow() { + public CommonDialogWindow getWindow(final Long editDistId) { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); - populateRequiredComponents(); resetComponents(); + + populateValuesOfDistribution(editDistId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), null, formLayout, i18n); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index 0bf9ef81b..30ee80317 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -77,8 +77,7 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Override protected void onEdit(final ClickEvent event) { - distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId()); - final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(); + final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId()); newDistWindow.setCaption(getI18n().get("caption.update.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java index b0ed19f8f..0e63ddb95 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTableHeader.java @@ -154,7 +154,7 @@ public class DistributionTableHeader extends AbstractTableHeader { @Override protected void addNewItem(final ClickEvent event) { - final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(); + final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(null); newDistWindow.setCaption(i18n.get("caption.add.new.dist")); UI.getCurrent().addWindow(newDistWindow); newDistWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java deleted file mode 100644 index c906a87dd..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/CommonDialogWindowHelper.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.eclipse.hawkbit.ui.utils; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import com.vaadin.ui.AbstractField; -import com.vaadin.ui.Component; -import com.vaadin.ui.FormLayout; - -public class CommonDialogWindowHelper { - - /** - * Run through a FormLayout and collect all required Component's IDs in a - * Map - * - * @param formLayout - * Form to be analysed - * @return Map with all required component's IDs - */ - public static Map getMandatoryFields(final FormLayout formLayout) { - final Map requiredFields = new HashMap<>(); - final Iterator iterate = formLayout.iterator(); - while (iterate.hasNext()) { - final Component c = iterate.next(); - if (c instanceof AbstractField && ((AbstractField) c).isRequired()) { - requiredFields.put(c.getId(), Boolean.FALSE); - } - } - return requiredFields; - } -} From 7e32cbd21c9a317e79e90b639a86f66fa5536b2b Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 17:38:21 +0200 Subject: [PATCH 66/82] Add table items comparison to enable save button Signed-off-by: SirWayne --- hawkbit-ui/pom.xml | 4 ++ .../hawkbit/ui/common/CommonDialogWindow.java | 65 +++++++++++++------ pom.xml | 6 ++ 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/hawkbit-ui/pom.xml b/hawkbit-ui/pom.xml index 08d225c62..b90e36e88 100644 --- a/hawkbit-ui/pom.xml +++ b/hawkbit-ui/pom.xml @@ -200,6 +200,10 @@ org.springframework.security spring-security-web + + org.apache.commons + commons-collections4 + com.vaadin diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 888fd1409..7cba5df4a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -12,6 +12,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -20,6 +21,7 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -31,6 +33,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import com.google.common.base.Strings; +import com.google.common.collect.Sets; import com.vaadin.data.Container.ItemSetChangeEvent; import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Property.ValueChangeEvent; @@ -204,7 +207,7 @@ public class CommonDialogWindow extends Window implements Serializable { Object value = field.getValue(); if (field instanceof Table) { - value = ((Table) field).getContainerDataSource().getItemIds(); + value = Sets.newHashSet(((Table) field).getContainerDataSource().getItemIds()); } orginalValues.put(field, value); } @@ -214,13 +217,15 @@ public class CommonDialogWindow extends Window implements Serializable { private final void addListeners() { for (final AbstractField field : allComponents) { - field.addValueChangeListener(new ChangeListener(field)); + if (field instanceof TextChangeNotifier) { ((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field)); } if (field instanceof Table) { ((Table) field).addItemSetChangeListener(new ChangeListener(field)); + } else { + field.addValueChangeListener(new ChangeListener(field)); } } @@ -236,17 +241,10 @@ public class CommonDialogWindow extends Window implements Serializable { private boolean isValuesChanged(final Component currentChangedComponent, final Object newValue) { for (final AbstractField field : allComponents) { - Object orginalValue = orginalValues.get(field); - Object currentValue = field.getValue(); - if (field.equals(currentChangedComponent)) { - currentValue = newValue; - } + final Object orginalValue = orginalValues.get(field); + final Object currentValue = getCurrentVaue(currentChangedComponent, newValue, field); - if (String.class.equals(field.getType())) { - orginalValue = Strings.emptyToNull((String) orginalValue); - currentValue = Strings.emptyToNull((String) currentValue); - } - if (!Objects.equals(orginalValue, currentValue)) { + if (!isValueEquals(field, orginalValue, currentValue)) { return true; } @@ -254,6 +252,33 @@ public class CommonDialogWindow extends Window implements Serializable { return false; } + private boolean isValueEquals(final AbstractField field, final Object orginalValue, final Object currentValue) { + if (Set.class.equals(field.getType())) { + return CollectionUtils.isEqualCollection(CollectionUtils.emptyIfNull((Collection) orginalValue), + CollectionUtils.emptyIfNull((Collection) currentValue)); + } + + if (String.class.equals(field.getType())) { + return Objects.equals(Strings.emptyToNull((String) orginalValue), + Strings.emptyToNull((String) currentValue)); + } + + return Objects.equals(orginalValue, currentValue); + } + + private Object getCurrentVaue(final Component currentChangedComponent, final Object newValue, + final AbstractField field) { + Object currentValue = field.getValue(); + if (field instanceof Table) { + currentValue = ((Table) field).getContainerDataSource().getItemIds(); + } + + if (field.equals(currentChangedComponent)) { + currentValue = newValue; + } + return currentValue; + } + private boolean shouldMandatoryLabelShown() { for (final AbstractField field : allComponents) { if (field.isRequired()) { @@ -269,17 +294,14 @@ public class CommonDialogWindow extends Window implements Serializable { .collect(Collectors.toList()); for (final AbstractField field : requiredComponents) { - Object value = field.getValue(); - if (field.equals(currentChangedComponent)) { - value = newValue; - } + Object value = getCurrentVaue(currentChangedComponent, newValue, field); if (String.class.equals(field.getType())) { value = Strings.emptyToNull((String) value); } if (Set.class.equals(field.getType())) { - value = emptyToNull((Set) value); + value = emptyToNull((Collection) value); } if (value == null) { @@ -290,7 +312,7 @@ public class CommonDialogWindow extends Window implements Serializable { } - private static Object emptyToNull(final Set c) { + private static Object emptyToNull(final Collection c) { return (c == null || c.isEmpty()) ? null : c; } @@ -407,7 +429,12 @@ public class CommonDialogWindow extends Window implements Serializable { @Override public void containerItemSetChange(final ItemSetChangeEvent event) { - saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getContainer().getItemIds())); + if (!(field instanceof Table)) { + return; + } + final Table table = (Table) field; + saveButton.setEnabled( + isSaveButtonEnabledAfterValueChange(table, table.getContainerDataSource().getItemIds())); } } diff --git a/pom.xml b/pom.xml index 444883bba..5995b8faf 100644 --- a/pom.xml +++ b/pom.xml @@ -111,6 +111,7 @@ 1.1 1.1.1 3.4 + 4.0 20141113 2.0.0 @@ -560,6 +561,11 @@ commons-lang3 ${commons-lang3.version} + + org.apache.commons + commons-collections4 + ${commons-collections4.version} + org.springframework.boot spring-boot-starter-test From 9ce6e43b876e9b5f27a3a2c81a7959457a92f1a2 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 28 Jun 2016 17:49:16 +0200 Subject: [PATCH 67/82] Set value if rollout is edited Signed-off-by: SirWayne --- .../dstable/DistributionAddUpdateWindowLayout.java | 6 +++--- .../rollout/rollout/AddUpdateRolloutWindowLayout.java | 10 +++++++--- .../hawkbit/ui/rollout/rollout/RolloutListGrid.java | 3 +-- .../hawkbit/ui/rollout/rollout/RolloutListHeader.java | 3 +-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 3e60a20ab..c2f125e3a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -348,6 +348,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { private void populateValuesOfDistribution(final Long editDistId) { this.editDistId = editDistId; + if (editDistId == null) { return; } @@ -368,13 +369,12 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { if (distSet.getDescription() != null) { descTextArea.setValue(distSet.getDescription()); } - populateDistSetTypeNameCombo(); } public CommonDialogWindow getWindow(final Long editDistId) { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); resetComponents(); - + populateDistSetTypeNameCombo(); populateValuesOfDistribution(editDistId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), @@ -386,7 +386,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { /** * Populate DistributionSet Type name combo. */ - public void populateDistSetTypeNameCombo() { + private void populateDistSetTypeNameCombo() { distsetTypeNameComboBox.setContainerDataSource(getDistSetTypeLazyQueryContainer()); distsetTypeNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); distsetTypeNameComboBox.setValue(getDefaultDistributionSetType().getName()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index e03f72b1e..777682ff1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -155,8 +155,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } - public CommonDialogWindow getWindow() { + public CommonDialogWindow getWindow(final Long rolloutId) { resetComponents(); + populateData(rolloutId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); @@ -728,8 +729,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { * @param rolloutId * rollout id */ - public void populateData(final Long rolloutId) { - resetComponents(); + private void populateData(final Long rolloutId) { + if (rolloutId == null) { + return; + } + editRolloutEnabled = Boolean.TRUE; rolloutForEdit = rolloutManagement.findRolloutById(rolloutId); rolloutName.setValue(rolloutForEdit.getName()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 97bd4bd35..db4fbb929 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -431,8 +431,7 @@ public class RolloutListGrid extends AbstractGrid { } private void onUpdate(final ContextMenuData contextMenuData) { - addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId()); - final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(); + final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(contextMenuData.getRolloutId()); addTargetWindow.setCaption(i18n.get("caption.update.rollout")); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 1a3d2d7a5..49bb90100 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -91,8 +91,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { - addUpdateRolloutWindow.resetComponents(); - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); + final Window addTargetWindow = addUpdateRolloutWindow.getWindow(null); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); From 8cd6e5d614b3f5c711d65f4fc82881e4c8391d1d Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 14:20:40 +0200 Subject: [PATCH 68/82] Made queue declaration retry count configurable. Signed-off-by: Kai Zimmermann --- .../hawkbit/amqp/AmqpConfiguration.java | 13 ++--- .../amqp/AmqpMessageHandlerService.java | 34 ++++++------- .../eclipse/hawkbit/amqp/AmqpProperties.java | 23 +++++++++ ...gurableRabbitListenerContainerFactory.java | 49 +++++++++++++++++++ 4 files changed, 89 insertions(+), 30 deletions(-) create mode 100644 hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 538f82213..11f892654 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -22,11 +22,11 @@ import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.QueueBuilder; -import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.beans.factory.annotation.Autowired; @@ -268,15 +268,8 @@ public class AmqpConfiguration { * AMQP messages */ @Bean(name = { "listenerContainerFactory" }) - public SimpleRabbitListenerContainerFactory listenerContainerFactory() { - final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory(); - containerFactory.setDefaultRequeueRejected(true); - containerFactory.setConnectionFactory(rabbitConnectionFactory); - containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); - containerFactory.setConcurrentConsumers(amqpProperties.getInitialConcurrentConsumers()); - containerFactory.setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers()); - containerFactory.setPrefetchCount(amqpProperties.getPrefetchCount()); - return containerFactory; + public RabbitListenerContainerFactory listenerContainerFactory() { + return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory); } private static Map getTTLMaxArgsAuthenticationQueue() { diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index b003d316a..9636de5c7 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -138,9 +138,18 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory") - public Message onAuthenticationRequest(final Message message, - @Header(MessageHeaderKey.TENANT) final String tenant) { - return onAuthenticationRequest(message); + public Message onAuthenticationRequest(final Message message) { + checkContentTypeJson(message); + final SecurityContext oldContext = SecurityContextHolder.getContext(); + try { + return handleAuthentifiactionMessage(message); + } catch (final IllegalArgumentException ex) { + throw new AmqpRejectAndDontRequeueException("Invalid message!", ex); + } catch (final TenantNotExistException teex) { + throw new AmqpRejectAndDontRequeueException(teex); + } finally { + SecurityContextHolder.setContext(oldContext); + } } public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) { @@ -159,7 +168,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService { final EventTopic eventTopic = EventTopic.valueOf(topicValue); handleIncomingEvent(message, eventTopic); break; - default: logAndThrowMessageError(message, "No handle method was found for the given message type."); } @@ -173,20 +181,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return null; } - public Message onAuthenticationRequest(final Message message) { - checkContentTypeJson(message); - final SecurityContext oldContext = SecurityContextHolder.getContext(); - try { - return handleAuthentifiactionMessage(message); - } catch (final IllegalArgumentException ex) { - throw new AmqpRejectAndDontRequeueException("Invalid message!", ex); - } catch (final TenantNotExistException teex) { - throw new AmqpRejectAndDontRequeueException(teex); - } finally { - SecurityContextHolder.setContext(oldContext); - } - } - private Message handleAuthentifiactionMessage(final Message message) { final DownloadResponse authentificationResponse = new DownloadResponse(); final MessageProperties messageProperties = message.getMessageProperties(); @@ -414,7 +408,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { if (ArrayUtils.isNotEmpty(message.getMessageProperties().getCorrelationId())) { actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " - + message.getMessageProperties().getCorrelationId()); + + new String(message.getMessageProperties().getCorrelationId())); } actionStatus.setAction(action); @@ -466,7 +460,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) { return; } - throw new IllegalArgumentException("Content-Type is not JSON compatible"); + throw new AmqpRejectAndDontRequeueException("Content-Type is not JSON compatible"); } void setControllerManagement(final ControllerManagement controllerManagement) { diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java index 888b204e7..56aa37772 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpProperties.java @@ -68,6 +68,29 @@ public class AmqpProperties { */ private int initialConcurrentConsumers = 3; + /** + * The number of retry attempts when passive queue declaration fails. + * Passive queue declaration occurs when the consumer starts or, when + * consuming from multiple queues, when not all queues were available during + * initialization. + */ + private int declarationRetries = 50; + + /** + * @return the declarationRetries + */ + public int getDeclarationRetries() { + return declarationRetries; + } + + /** + * @param declarationRetries + * the declarationRetries to set + */ + public void setDeclarationRetries(final int declarationRetries) { + this.declarationRetries = declarationRetries; + } + public String getAuthenticationReceiverQueue() { return authenticationReceiverQueue; } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java new file mode 100644 index 000000000..fd0a1d2a1 --- /dev/null +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.amqp; + +import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; +import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; + +/** + * {@link RabbitListenerContainerFactory} that can be configured through + * hawkBit's {@link AmqpProperties}. + * + */ +public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitListenerContainerFactory { + private final AmqpProperties amqpProperties; + + /** + * Constructor. + * + * @param rabbitConnectionFactory + * for the container factory + * @param amqpProperties + * to configure the container factory + */ + public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties, + final ConnectionFactory rabbitConnectionFactory) { + this.amqpProperties = amqpProperties; + setDefaultRequeueRejected(true); + setConnectionFactory(rabbitConnectionFactory); + setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); + setConcurrentConsumers(amqpProperties.getInitialConcurrentConsumers()); + setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers()); + setPrefetchCount(amqpProperties.getPrefetchCount()); + + } + + @Override + protected void initializeContainer(final SimpleMessageListenerContainer instance) { + super.initializeContainer(instance); + instance.setDeclarationRetries(amqpProperties.getDeclarationRetries()); + } +} From 0c4d88a8f4714f7087bc10702eec6e7b2a600bd6 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 15:15:06 +0200 Subject: [PATCH 69/82] Fixed test. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 6e61d1642..0dcf6cd85 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -141,7 +141,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); fail("IllegalArgumentException was excepeted due to worng content type"); - } catch (final IllegalArgumentException e) { + } catch (final AmqpRejectAndDontRequeueException e) { } } From 202054e129631d820440d0d1b1a8ee59565ad739 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 15:20:23 +0200 Subject: [PATCH 70/82] Fixed sonar issue. Signed-off-by: Kai Zimmermann --- .../amqp/ConfigurableRabbitListenerContainerFactory.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java index fd0a1d2a1..14e6f8fcb 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java @@ -42,6 +42,9 @@ public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitList } @Override + // Exception squid:UnusedProtectedMethod - called by + // AbstractRabbitListenerContainerFactory + @SuppressWarnings("squid:UnusedProtectedMethod") protected void initializeContainer(final SimpleMessageListenerContainer instance) { super.initializeContainer(instance); instance.setDeclarationRetries(amqpProperties.getDeclarationRetries()); From c3b999792b5190f943171c45e04aec2618d302a7 Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 16:18:35 +0200 Subject: [PATCH 71/82] Clarified string conversion. Signed-off-by: Kai Zimmermann --- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 9636de5c7..d1bf85103 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -408,7 +408,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { if (ArrayUtils.isNotEmpty(message.getMessageProperties().getCorrelationId())) { actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id " - + new String(message.getMessageProperties().getCorrelationId())); + + convertCorrelationId(message)); } actionStatus.setAction(action); @@ -416,6 +416,10 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return actionStatus; } + private static String convertCorrelationId(final Message message) { + return new String(message.getMessageProperties().getCorrelationId()); + } + private Action getUpdateActionStatus(final ActionStatus actionStatus) { if (actionStatus.getStatus().equals(Status.CANCELED)) { return controllerManagement.addCancelActionStatus(actionStatus); From 8d6526ae8fe25c164d46597b3966c74e0731571c Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Wed, 29 Jun 2016 17:01:24 +0200 Subject: [PATCH 72/82] Fixed fail messages. Signed-off-by: Kai Zimmermann --- .../amqp/AmqpMessageHandlerServiceTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 0dcf6cd85..2627731c6 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -140,7 +140,7 @@ public class AmqpMessageHandlerServiceTest { final Message message = new Message(new byte[0], messageProperties); try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to worng content type"); + fail("AmqpRejectAndDontRequeueException was excepeted due to worng content type"); } catch (final AmqpRejectAndDontRequeueException e) { } } @@ -175,7 +175,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no replyTo header was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no replyTo header was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -189,7 +189,7 @@ public class AmqpMessageHandlerServiceTest { final Message message = messageConverter.toMessage(new byte[0], messageProperties); try { amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no thingID was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no thingID was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -205,7 +205,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, type, TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to unknown message type"); + fail("AmqpRejectAndDontRequeueException was excepeted due to unknown message type"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -218,21 +218,21 @@ public class AmqpMessageHandlerServiceTest { final Message message = new Message(new byte[0], messageProperties); try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to unknown message type"); + fail("AmqpRejectAndDontRequeueException was excepeted due to unknown message type"); } catch (final AmqpRejectAndDontRequeueException e) { } try { messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic"); amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted due to unknown topic"); + fail("AmqpRejectAndDontRequeueException was excepeted due to unknown topic"); } catch (final AmqpRejectAndDontRequeueException e) { } messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name()); try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted because there was no event topic"); + fail("AmqpRejectAndDontRequeueException was excepeted because there was no event topic"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -251,7 +251,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no action id was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no action id was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } @@ -268,7 +268,7 @@ public class AmqpMessageHandlerServiceTest { try { amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost"); - fail("IllegalArgumentException was excepeted since no action id was set"); + fail("AmqpRejectAndDontRequeueException was excepeted since no action id was set"); } catch (final AmqpRejectAndDontRequeueException exception) { // test ok - exception was excepted } From f79073a15e72f76b0d351e6ec47ee90533b7c626 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Wed, 29 Jun 2016 19:16:17 +0200 Subject: [PATCH 73/82] Save button is only enabled if validation is successful Signed-off-by: Melanie Retter --- .../SoftwareModuleAddUpdateWindow.java | 49 +------ .../CreateUpdateSoftwareTypeLayout.java | 6 +- .../hawkbit/ui/common/CommonDialogWindow.java | 68 ++++++---- .../CreateUpdateDistSetTypeLayout.java | 58 +-------- .../AbstractCreateUpdateTagLayout.java | 49 ++----- .../ui/layouts/CreateUpdateTypeLayout.java | 5 - .../DistributionAddUpdateWindowLayout.java | 58 +-------- .../TargetAddUpdateWindowLayout.java | 55 +------- .../CreateUpdateTargetTagLayoutWindow.java | 1 - .../rollout/AddUpdateRolloutWindowLayout.java | 122 ++++++------------ 10 files changed, 110 insertions(+), 361 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java index 73346454d..c8eb74313 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java @@ -26,7 +26,6 @@ import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; @@ -40,7 +39,6 @@ import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** @@ -184,8 +182,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se setCompositionRoot(formLayout); window = SPUIWindowDecorator.getWindow(i18n.get("upload.caption.add.new.swmodule"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null, - formLayout, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), null, null, formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); nameTextField.setEnabled(!editSwModule); @@ -202,10 +199,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se final String description = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); final String type = typeComboBox.getValue() != null ? typeComboBox.getValue().toString() : null; - if (!mandatoryCheck(name, version, type)) { - return; - } - if (HawkbitCommonUtil.isDuplicate(name, version, type)) { uiNotifcation.displayValidationError( i18n.get("message.duplicate.softwaremodule", new Object[] { name, version })); @@ -218,8 +211,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se new Object[] { newBaseSoftwareModule.getName() + ":" + newBaseSoftwareModule.getVersion() })); eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.NEW_ENTITY, newBaseSoftwareModule)); } - // close the window - closeThisWindow(); } } @@ -239,7 +230,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.UPDATED_ENTITY, newSWModule)); } - closeThisWindow(); } /** @@ -249,6 +239,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se if (baseSwModuleId == null) { return; } + editSwModule = Boolean.TRUE; final SoftwareModule swModle = softwareManagement.findSoftwareModuleById(baseSwModuleId); nameTextField.setValue(swModle.getName()); versionTextField.setValue(swModle.getVersion()); @@ -262,42 +253,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se typeComboBox.setValue(swModle.getType().getName()); } - /** - * Method to close window. - */ - private void closeThisWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - - /** - * Validation check - Mandatory. - * - * @param name - * as String - * @param version - * as version - * @return boolena as flag - */ - private boolean mandatoryCheck(final String name, final String version, final String type) { - boolean isValid = true; - if (name == null || version == null || type == null) { - if (name == null) { - nameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (version == null) { - versionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (type == null) { - typeComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); - } - - uiNotifcation.displayValidationError(i18n.get("message.mandatory.check")); - isValid = false; - } - return isValid; - } - private void saveOrUpdate() { if (editSwModule) { updateSwModule(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 3ca0e3631..18d6b159c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -36,7 +36,6 @@ import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.components.colorpicker.ColorChangeListener; -import com.vaadin.ui.components.colorpicker.ColorSelector; import com.vaadin.ui.themes.ValoTheme; /** @@ -45,8 +44,7 @@ import com.vaadin.ui.themes.ValoTheme; */ @SpringComponent @ViewScope -public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout - implements ColorChangeListener, ColorSelector { +public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { private static final long serialVersionUID = -5169398523815919367L; private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateSoftwareTypeLayout.class); @@ -231,7 +229,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout newSWType = swTypeManagementService.createSoftwareModuleType(newSWType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newSWType.getName() })); - closeWindow(); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType)); @@ -253,7 +250,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout existingType.setColour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); swTypeManagementService.updateSoftwareModuleType(existingType); uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() })); - closeWindow(); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType)); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 7cba5df4a..1d2f3b2d4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -31,6 +31,7 @@ import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent; import com.google.common.base.Strings; import com.google.common.collect.Sets; @@ -38,6 +39,8 @@ import com.vaadin.data.Container.ItemSetChangeEvent; import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.data.Validator; +import com.vaadin.data.validator.NullValidator; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.event.FieldEvents.TextChangeNotifier; @@ -64,6 +67,7 @@ import com.vaadin.ui.themes.ValoTheme; * * Table pop-up-windows including a minimize and close icon in the upper right * corner and a save and cancel button at the bottom. Is not intended to reuse. + * */ public class CommonDialogWindow extends Window implements Serializable { @@ -89,6 +93,8 @@ public class CommonDialogWindow extends Window implements Serializable { private final ClickListener cancelButtonClickListener; + private final ClickListener close = event -> close(); + private final Map orginalValues; private final List> allComponents; @@ -113,7 +119,6 @@ public class CommonDialogWindow extends Window implements Serializable { final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, final AbstractLayout layout, final I18N i18n) { checkNotNull(saveButtonClickListener); - checkNotNull(cancelButtonClickListener); this.caption = caption; this.content = content; this.helpLink = helpLink; @@ -211,13 +216,11 @@ public class CommonDialogWindow extends Window implements Serializable { } orginalValues.put(field, value); } - saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null)); } private final void addListeners() { for (final AbstractField field : allComponents) { - if (field instanceof TextChangeNotifier) { ((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field)); } @@ -229,13 +232,13 @@ public class CommonDialogWindow extends Window implements Serializable { } } - saveButton.addClickListener(event -> close()); - cancelButton.addClickListener(event -> close()); + saveButton.addClickListener(close); + cancelButton.addClickListener(close); } private boolean isSaveButtonEnabledAfterValueChange(final Component currentChangedComponent, final Object newValue) { - return isMandatoyFieldNotEmpty(currentChangedComponent, newValue) + return isMandatoryFieldNotEmptyAndValid(currentChangedComponent, newValue) && isValuesChanged(currentChangedComponent, newValue); } @@ -247,7 +250,6 @@ public class CommonDialogWindow extends Window implements Serializable { if (!isValueEquals(field, orginalValue, currentValue)) { return true; } - } return false; } @@ -289,31 +291,45 @@ public class CommonDialogWindow extends Window implements Serializable { return false; } - private boolean isMandatoyFieldNotEmpty(final Component currentChangedComponent, final Object newValue) { + private boolean isMandatoryFieldNotEmptyAndValid(final Component currentChangedComponent, final Object newValue) { + + boolean valid = true; final List> requiredComponents = allComponents.stream().filter(field -> field.isRequired()) .collect(Collectors.toList()); - for (final AbstractField field : requiredComponents) { - Object value = getCurrentVaue(currentChangedComponent, newValue, field); + requiredComponents.addAll(allComponents.stream().filter(this::hasNullValidator).collect(Collectors.toList())); - if (String.class.equals(field.getType())) { - value = Strings.emptyToNull((String) value); - } - - if (Set.class.equals(field.getType())) { - value = emptyToNull((Collection) value); - } + for (final AbstractField field : requiredComponents) { + final Object value = getCurrentVaue(currentChangedComponent, newValue, field); if (value == null) { return false; } - } - return true; + // We need to loop through the entire loop for validity testing. + // Otherwise the UI will only mark the + // first field with errors and then stop. If there are several + // fields with errors, this is bad. + field.setValue(value); + if (!field.isValid()) { + valid = false; + } + } + + return valid; } - private static Object emptyToNull(final Collection c) { - return (c == null || c.isEmpty()) ? null : c; + private boolean hasNullValidator(final Component component) { + + if (component instanceof AbstractField) { + final AbstractField fieldComponent = (AbstractField) component; + for (final Validator validator : fieldComponent.getValidators()) { + if (validator instanceof NullValidator) { + return true; + } + } + } + return false; } private List> getAllComponents(final AbstractLayout abstractLayout) { @@ -329,6 +345,10 @@ public class CommonDialogWindow extends Window implements Serializable { if (c instanceof AbstractField) { components.add((AbstractField) c); } + + if (c instanceof FlexibleOptionGroupItemComponent) { + components.add(((FlexibleOptionGroupItemComponent) c).getOwner()); + } } return components; } @@ -374,7 +394,9 @@ public class CommonDialogWindow extends Window implements Serializable { FontAwesome.TIMES, SPUIButtonStyleBorderWithIcon.class); cancelButton.setSizeUndefined(); cancelButton.addStyleName("default-color"); - cancelButton.addClickListener(cancelButtonClickListener); + if (cancelButtonClickListener != null) { + cancelButton.addClickListener(cancelButtonClickListener); + } buttonsLayout.addComponent(cancelButton); buttonsLayout.setComponentAlignment(cancelButton, Alignment.MIDDLE_LEFT); @@ -419,7 +441,6 @@ public class CommonDialogWindow extends Window implements Serializable { @Override public void textChange(final TextChangeEvent event) { saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getText())); - } @Override @@ -436,7 +457,6 @@ public class CommonDialogWindow extends Window implements Serializable { saveButton.setEnabled( isSaveButtonEnabledAfterValueChange(table, table.getContainerDataSource().getItemIds())); } - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index cc73e3467..122599520 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.distributions.disttype; -import java.util.Iterator; import java.util.List; import java.util.Set; @@ -49,8 +48,6 @@ import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.components.colorpicker.ColorChangeListener; -import com.vaadin.ui.components.colorpicker.ColorSelector; import com.vaadin.ui.themes.ValoTheme; /** @@ -58,8 +55,7 @@ import com.vaadin.ui.themes.ValoTheme; */ @SpringComponent @ViewScope -public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout - implements ColorChangeListener, ColorSelector { +public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { private static final long serialVersionUID = -5169398523815877767L; private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateDistSetTypeLayout.class); @@ -259,9 +255,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addTargetTableData(id); } - // TODO: Add Table to window - // window.updateRequiredFields(selectedTable.getId(), - // hasContentChanged()); } private void removeSMType() { @@ -274,40 +267,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout for (final Long id : selectedIds) { addSourceTableData(id); selectedTable.removeItem(id); - // window.updateRequiredFields(selectedTable.getId(), - // hasContentChanged()); } } - private Boolean hasContentChanged() { - - if (originalSelectedTableContainer == null) { - originalSelectedTableContainer = new IndexedContainer(); - } - // is new softwareModule added? - for (final Iterator itemIterator = selectedTableContainer.getItemIds().iterator(); itemIterator.hasNext();) { - final long itemId = (Long) itemIterator.next(); - if (!originalSelectedTableContainer.containsId(itemId)) { - // window.updateEditedFields(selectedTable.getId(), - // Boolean.TRUE); - return Boolean.TRUE; - } - } - - // is softwareModule removed and at least one softwareModule is selected - for (final Iterator itemIterator = originalSelectedTableContainer.getItemIds().iterator(); itemIterator - .hasNext();) { - final long itemId = (Long) itemIterator.next(); - if (selectedTableContainer.size() > 0 && !selectedTableContainer.containsId(itemId)) { - // window.updateEditedFields(selectedTable.getId(), - // Boolean.TRUE); - return Boolean.TRUE; - } - } - - return Boolean.FALSE; - } - @SuppressWarnings("unchecked") private void getSourceTableData() { @@ -402,10 +364,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout newDistType.setColour(colorPicked); newDistType = distributionSetManagement.createDistributionSetType(newDistType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newDistType.getName() })); - closeWindow(); eventBus.publish(this, new DistributionSetTypeEvent(DistributionSetTypeEnum.ADD_DIST_SET_TYPE, newDistType)); - } else { uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey")); } @@ -445,7 +405,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout distributionSetManagement.updateDistributionSetType(updateDistSetType); uiNotification .displaySuccess(i18n.get("message.update.success", new Object[] { updateDistSetType.getName() })); - closeWindow(); eventBus.publish(this, new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType)); @@ -480,18 +439,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout return distSetType; } - @Override - public void addColorChangeListener(final ColorChangeListener listener) { - - LOG.info("in side addColorChangeListener() "); - } - - @Override - public void removeColorChangeListener(final ColorChangeListener listener) { - - LOG.info("in side removeColorChangeListener() "); - } - /** * reset the components. */ @@ -515,7 +462,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout super.optionValueChanged(event); if (updateTypeStr.equals(event.getProperty().getValue())) { - // window.updateRequiredFields(selectedTable.getId(), Boolean.TRUE); selectedTable.getContainerDataSource().removeAllItems(); getSourceTableData(); distTypeSelectLayout.setEnabled(false); @@ -616,6 +562,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout sourceTable.removeItem(swModuleType.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + + // TODO CHECKBOX final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 8c85f63a5..6527d5db5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -30,7 +30,6 @@ import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; -import com.google.common.base.Strings; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.server.Page; @@ -335,7 +334,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor()); colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor()); tagPreviewBtnClicked = false; - } /** @@ -427,11 +425,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } - protected void closeWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - /** * create option group with Create tag/Update tag based on permissions. */ @@ -463,14 +456,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent } } - @Override - public void addColorChangeListener(final ColorChangeListener listener) { - } - - @Override - public void removeColorChangeListener(final ColorChangeListener listener) { - } - public ColorPickerLayout getColorPickerLayout() { return colorPickerLayout; } @@ -554,7 +539,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent tagManagement.updateDistributionSetTag((DistributionSetTag) targetObj); } uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() })); - closeWindow(); } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } @@ -576,27 +560,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent getPreviewButtonColor(previewColor); } - /** - * - * @return - */ - protected Boolean mandatoryValuesPresent() { - if (Strings.isNullOrEmpty(tagName.getValue())) { - if (optiongroup.getValue().equals(createTagStr)) { - displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME); - } - if (optiongroup.getValue().equals(updateTagStr)) { - if (null == tagNameComboBox.getValue()) { - displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME)); - } else { - displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME); - } - } - return Boolean.FALSE; - } - return Boolean.TRUE; - } - protected Boolean checkIsDuplicate(final Tag existingTag) { if (existingTag != null) { displayValidationError(i18n.get("message.tag.duplicate.check", new Object[] { existingTag.getName() })); @@ -637,4 +600,16 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent return mainLayout; } + @Override + public void addColorChangeListener(final ColorChangeListener listener) { + // TODO Auto-generated method stub + + } + + @Override + public void removeColorChangeListener(final ColorChangeListener listener) { + // TODO Auto-generated method stub + + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java index 47451d662..f25a4b485 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/CreateUpdateTypeLayout.java @@ -179,11 +179,6 @@ public abstract class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayo createDynamicStyleForComponents(tagName, typeKey, tagDesc, colorPickedPreview); getColorPickerLayout().getColorSelect().setColor(getColorPickerLayout().getSelPreview().getColor()); } - - // TODO: - // window.checkColorChange(colorPickerLayout.getId(), - // colorPickerLayout.getSelectedColor(), - // getOriginalSelectedColor()); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index c2f125e3a..069b9b407 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -50,7 +50,6 @@ import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** @@ -192,7 +191,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { final String distSetTypeName = HawkbitCommonUtil .trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue()); - if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) { + if (duplicateCheck(name, version)) { final DistributionSet currentDS = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId); final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); final boolean isMigStepReq = reqMigStepCheckbox.getValue(); @@ -210,7 +209,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { notificationMessage.displayValidationError( i18n.get("message.distribution.no.update", currentDS.getName() + ":" + currentDS.getVersion())); } - closeThisWindow(); } } @@ -224,7 +222,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { final String distSetTypeName = HawkbitCommonUtil .trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue()); - if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) { + if (duplicateCheck(name, version)) { final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); final boolean isMigStepReq = reqMigStepCheckbox.getValue(); DistributionSet newDist = entityFactory.generateDistributionSet(); @@ -234,21 +232,11 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success", new Object[] { newDist.getName(), newDist.getVersion() })); - /* close the window */ - closeThisWindow(); eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.NEW_ENTITY, newDist)); } } - /** - * Close window. - */ - private void closeThisWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - /** * Set Values for Distribution set. * @@ -292,45 +280,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { } } - /** - * Mandatory Check. - * - * @param name - * as String - * @param version - * as String - * @param selectedJVM - * as String - * @param selectedAgentHub - * as String - * @param selectedOs - * as String - * @return boolean as flag - */ - private boolean mandatoryCheck(final String name, final String version, final String distSetTypeName) { - - if (name == null || version == null || distSetTypeName == null) { - if (name == null) { - distNameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (version == null) { - distVersionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - } - if (distSetTypeName == null) { - distsetTypeNameComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR); - } - notificationMessage.displayValidationError(i18n.get("message.mandatory.check")); - return false; - } - - return true; - } - - private void discardDistribution() { - /* Just close this window */ - closeThisWindow(); - } - /** * clear all the fields. */ @@ -377,8 +326,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { populateDistSetTypeNameCombo(); populateValuesOfDistribution(editDistId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(), - null, formLayout, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), null, null, formLayout, i18n); window.getButtonsLayout().removeStyleName("actionButtonsMargin"); return window; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index fb7307f5f..93c5a4514 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -8,9 +8,7 @@ */ package org.eclipse.hawkbit.ui.management.targettable; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.EntityFactory; @@ -40,7 +38,6 @@ import com.vaadin.ui.CustomComponent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; @@ -75,10 +72,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { private FormLayout formLayout; private CommonDialogWindow window; - private String originalTargetName; - private String originalTargetDesc; - private String originalControllerId; - /** * Initialize the Add Update Window Component for Target. */ @@ -139,10 +132,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { uINotification.displaySuccess(i18n.get("message.update.success", new Object[] { latestTarget.getName() })); // publishing through event bus eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.UPDATED_ENTITY, latestTarget)); - - /* close the window */ - closeThisWindow(); - /* update details in table */ } private void saveTargetListner() { @@ -153,13 +142,9 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { } } - private void discardTargetListner() { - closeThisWindow(); - } - private void addNewTarget() { final String newControlllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerIDTextField.getValue()); - if (mandatoryCheck(newControlllerId) && duplicateCheck(newControlllerId)) { + if (duplicateCheck(newControlllerId)) { final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue()); final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue()); @@ -176,27 +161,16 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { /* display success msg */ uINotification.displaySuccess(i18n.get("message.save.success", new Object[] { newTarget.getName() })); - /* close the window */ - closeThisWindow(); } } public Window getWindow() { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.target"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), - event -> discardTargetListner(), null, formLayout, i18n); + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), null, null, formLayout, i18n); return window; } - private Map getEditedFields() { - final Map editedFields = new HashMap<>(); - editedFields.put(controllerIDTextField.getId(), Boolean.FALSE); - editedFields.put(nameTextField.getId(), Boolean.FALSE); - editedFields.put(descTextArea.getId(), Boolean.FALSE); - return editedFields; - } - /** * clear all fields of Target Edit Window. */ @@ -208,17 +182,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { controllerIDTextField.clear(); descTextArea.clear(); editTarget = Boolean.FALSE; - - originalControllerId = null; - originalTargetDesc = null; - originalTargetName = null; - - } - - private void closeThisWindow() { - editTarget = Boolean.FALSE; - window.close(); - UI.getCurrent().removeWindow(window); } private void setTargetValues(final Target target, final String name, final String description) { @@ -226,16 +189,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { target.setDescription(description); } - private boolean mandatoryCheck(final String newControlllerId) { - if (newControlllerId == null) { - controllerIDTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR); - uINotification.displayValidationError("Mandatory details are missing"); - return false; - } else { - return true; - } - } - private boolean duplicateCheck(final String newControlllerId) { final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim()); if (existingTarget != null) { @@ -261,10 +214,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { if (target.getDescription() != null) { descTextArea.setValue(target.getDescription()); } - - originalTargetDesc = descTextArea.getValue(); - originalTargetName = nameTextField.getValue(); - originalControllerId = controllerIDTextField.getValue(); window.addStyleName("target-update-window"); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java index 765704da8..f96c3b174 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayoutWindow.java @@ -129,7 +129,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa } newTargetTag = tagManagement.createTargetTag(newTargetTag); displaySuccess(newTargetTag.getName()); - closeWindow(); } else { displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME)); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 777682ff1..f97f8e43f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -12,7 +12,6 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.RolloutManagement; @@ -58,8 +57,9 @@ import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Validator; +import com.vaadin.data.util.converter.StringToIntegerConverter; import com.vaadin.data.validator.IntegerRangeValidator; -import com.vaadin.data.validator.RegexpValidator; +import com.vaadin.data.validator.NullValidator; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; @@ -69,7 +69,6 @@ import com.vaadin.ui.Label; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.TextArea; import com.vaadin.ui.TextField; -import com.vaadin.ui.UI; import com.vaadin.ui.themes.ValoTheme; /** @@ -87,8 +86,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private static final String MESSAGE_ENTER_NUMBER = "message.enter.number"; - private static final String NUMBER_REGEXP = "[-]?[0-9]*\\.?,?[0-9]+"; - @Autowired private ActionTypeOptionGroupLayout actionTypeOptionGroupLayout; @@ -146,6 +143,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextArea targetFilterQuery; + private final NullValidator nullValidator = new NullValidator(null, false); + /** * Create components and layout. */ @@ -157,10 +156,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { public CommonDialogWindow getWindow(final Long rolloutId) { resetComponents(); - populateData(rolloutId); window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(), + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null, uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); + populateData(rolloutId); return window; } @@ -207,33 +206,34 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { addComponent(getMandatoryLabel("textfield.name"), 0, 0); addComponent(rolloutName, 1, 0); - rolloutName.setRequired(true); + rolloutName.addValidator(nullValidator); addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1); addComponent(distributionSet, 1, 1); - distributionSet.setRequired(true); + distributionSet.addValidator(nullValidator); addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2); addComponent(targetFilterQueryCombo, 1, 2); - targetFilterQueryCombo.setRequired(true); + targetFilterQueryCombo.addValidator(nullValidator); + targetFilterQuery.removeValidator(nullValidator); addComponent(totalTargetsLabel, 2, 2); addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3); addComponent(noOfGroups, 1, 3); - noOfGroups.setRequired(true); + noOfGroups.addValidator(nullValidator); addComponent(groupSizeLabel, 2, 3); addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4); addComponent(triggerThreshold, 1, 4); - triggerThreshold.setRequired(true); + triggerThreshold.addValidator(nullValidator); addComponent(getPercentHintLabel(), 2, 4); addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5); addComponent(errorThreshold, 1, 5); - errorThreshold.setRequired(true); + errorThreshold.addValidator(nullValidator); addComponent(errorThresholdOptionGroup, 2, 5); addComponent(getLabel("textfield.description"), 0, 6); @@ -386,10 +386,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { targetFilterQF); } - private void onDiscard() { - closeThisWindow(); - } - private void onRolloutSave() { if (editRolloutEnabled) { editRollout(); @@ -399,7 +395,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void editRollout() { - if (mandatoryCheckForEdit() && validateFields() && duplicateCheckForEdit() && null != rolloutForEdit) { + if (duplicateCheckForEdit() && rolloutForEdit != null) { rolloutForEdit.setName(rolloutName.getValue()); rolloutForEdit.setDescription(description.getValue()); final DistributionSetIdName distributionSetIdName = (DistributionSetIdName) distributionSet.getValue(); @@ -417,7 +413,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { final Rollout updatedRollout = rolloutManagement.updateRollout(rolloutForEdit); uiNotification .displaySuccess(i18n.get("message.update.success", new Object[] { updatedRollout.getName() })); - closeThisWindow(); eventBus.publish(this, RolloutEvent.UPDATE_ROLLOUT); } } @@ -445,11 +440,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } private void createRollout() { - if (mandatoryCheck() && validateFields() && duplicateCheck()) { + if (duplicateCheck()) { final Rollout rolloutToCreate = saveRollout(); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { rolloutToCreate.getName() })); eventBus.publish(this, RolloutEvent.CREATE_ROLLOUT); - closeThisWindow(); } } @@ -506,48 +500,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return true; } - private void closeThisWindow() { - window.close(); - UI.getCurrent().removeWindow(window); - } - - private boolean mandatoryCheck() { - final DistributionSetIdName ds = getDistributionSetSelected(); - final String targetFilter = (String) targetFilterQueryCombo.getValue(); - final String triggerThresoldValue = triggerThreshold.getValue(); - final String errorThresoldValue = errorThreshold.getValue(); - if (hasNoNameOrTargetFilter(targetFilter) || ds == null - || HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) { - uiNotification.displayValidationError(i18n.get("message.mandatory.check")); - return false; - } - return true; - } - - private boolean mandatoryCheckForEdit() { - final DistributionSetIdName ds = getDistributionSetSelected(); - final String targetFilter = targetFilterQuery.getValue(); - final String triggerThresoldValue = triggerThreshold.getValue(); - final String errorThresoldValue = errorThreshold.getValue(); - if (hasNoNameOrTargetFilter(targetFilter) || ds == null - || HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) { - uiNotification.displayValidationError(i18n.get("message.mandatory.check")); - return false; - } - return true; - } - - private boolean hasNoNameOrTargetFilter(final String targetFilter) { - return getRolloutName() == null || targetFilter == null; - } - - private boolean isThresholdValueMissing(final String triggerThresoldValue, final String errorThresoldValue) { - return HawkbitCommonUtil.trimAndNullIfEmpty(triggerThresoldValue) == null - || HawkbitCommonUtil.trimAndNullIfEmpty(errorThresoldValue) == null; - } - private boolean duplicateCheck() { if (rolloutManagement.findRolloutByName(getRolloutName()) != null) { uiNotification.displayValidationError( @@ -573,7 +525,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextField createErrorThreshold() { final TextField errorField = getTextfield("prompt.error.threshold"); + errorField.setNullRepresentation(""); errorField.addValidator(new ThresholdFieldValidator()); + errorField.setConverter(new StringToIntegerConverter()); + errorField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID); errorField.setMaxLength(7); errorField.setSizeUndefined(); @@ -583,7 +538,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private TextField createTriggerThreshold() { final TextField thresholdField = getTextfield("prompt.tigger.threshold"); thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID); + thresholdField.setNullRepresentation(""); thresholdField.addValidator(new ThresholdFieldValidator()); + thresholdField.setConverter(new StringToIntegerConverter()); + thresholdField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); thresholdField.setSizeUndefined(); thresholdField.setMaxLength(3); return thresholdField; @@ -595,12 +553,15 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroupsField.addValidator(new GroupNumberValidator()); noOfGroupsField.setSizeUndefined(); noOfGroupsField.setMaxLength(3); + noOfGroupsField.setConverter(new StringToIntegerConverter()); + noOfGroupsField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER)); noOfGroupsField.addValueChangeListener(this::onGroupNumberChange); + noOfGroupsField.setNullRepresentation(""); return noOfGroupsField; } private void onGroupNumberChange(final ValueChangeEvent event) { - if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) { + if (event.getProperty().getValue() != null && noOfGroups.isValid()) { groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize()))); groupSizeLabel.setVisible(true); } else { @@ -643,10 +604,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { return HawkbitCommonUtil.trimAndNullIfEmpty(rolloutName.getValue()); } - private DistributionSetIdName getDistributionSetSelected() { - return (DistributionSetIdName) distributionSet.getValue(); - } - class ErrorThresoldOptionValidator implements Validator { private static final long serialVersionUID = 9049939751976326550L; @@ -659,8 +616,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { - if (StringUtils.isNotBlank(value.toString())) { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + if (value != null) { final int groupSize = getGroupSize(); new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, groupSize).validate(Integer.valueOf(value.toString())); @@ -670,8 +626,12 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { - LOG.error(ex.getMessage()); + catch ( + + @SuppressWarnings("squid:S1166") final InvalidValueException ex) { + // we have to throw the exception here, otherwise the UI won't + // show the vaadin validation error! + throw ex; } } } @@ -686,8 +646,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - if (StringUtils.isNotBlank(value.toString())) { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + if (value != null) { new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100) .validate(Integer.valueOf(value.toString())); } @@ -696,7 +655,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // up the // log and not necessary here catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { - LOG.error(ex.getMessage()); + // we have to throw the exception here, otherwise the UI won't + // show the vaadin validation error! + throw ex; } } } @@ -707,8 +668,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - if (StringUtils.isNotBlank(value.toString())) { - new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value); + if (value != null) { new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500) .validate(Integer.valueOf(value.toString())); } @@ -717,7 +677,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // up the // log and not necessary here catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { - LOG.error(ex.getMessage()); + // we have to throw the exception here, otherwise the UI won't + // show the vaadin validation error! + throw ex; } } } @@ -749,7 +711,9 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { noOfGroups.setEnabled(false); targetFilterQuery.setValue(rolloutForEdit.getTargetFilterQuery()); removeComponent(1, 2); + targetFilterQueryCombo.removeValidator(nullValidator); addComponent(targetFilterQuery, 1, 2); + targetFilterQuery.addValidator(nullValidator); totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(rolloutForEdit.getTargetFilterQuery()); totalTargetsLabel.setValue(getTotalTargetMessage()); @@ -795,7 +759,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { * @param rolloutGroups */ private void setThresholdValues(final List rolloutGroups) { - if (null != rolloutGroups && !rolloutGroups.isEmpty()) { + if (rolloutGroups != null && !rolloutGroups.isEmpty()) { errorThreshold.setValue(rolloutGroups.get(0).getErrorConditionExp()); triggerThreshold.setValue(rolloutGroups.get(0).getSuccessConditionExp()); noOfGroups.setValue(String.valueOf(rolloutGroups.size())); From fa2e801e7648a4c68fe897220f2ec46f44d50dab Mon Sep 17 00:00:00 2001 From: venu1278 Date: Thu, 30 Jun 2016 14:50:20 +0530 Subject: [PATCH 74/82] RolloutView_update_automaticaly_changes_in_repository Signed-off-by: venu1278 --- .../org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index 20c2ca710..d16060eea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -145,6 +145,7 @@ public class RolloutListGrid extends AbstractGrid { final LazyQueryContainer rolloutContainer = (LazyQueryContainer) getContainerDataSource(); final Item item = rolloutContainer.getItem(rolloutChangeEvent.getRolloutId()); if (item == null) { + refreshGrid(); return; } item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus()); From 67ee674d412da216644813fe4ddcd7b81c95b8af Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 30 Jun 2016 17:48:58 +0200 Subject: [PATCH 75/82] Fix Update bug of softwareModuleType, refactored based on git comments Signed-off-by: Melanie Retter --- .../repository/jpa/JpaSoftwareManagement.java | 2 +- .../CreateUpdateSoftwareTypeLayout.java | 15 +------ .../hawkbit/ui/common/CommonDialogWindow.java | 40 +++++++++++++++++-- .../CreateUpdateDistSetTypeLayout.java | 29 +++++++------- .../AbstractCreateUpdateTagLayout.java | 4 -- .../TargetAddUpdateWindowLayout.java | 10 ++++- .../management/targettable/TargetDetails.java | 3 +- .../rollout/AddUpdateRolloutWindowLayout.java | 30 ++++++++------ .../ui/rollout/rollout/RolloutListHeader.java | 2 +- 9 files changed, 83 insertions(+), 52 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index 50127e227..b561667a9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -132,7 +132,7 @@ public class JpaSoftwareManagement implements SoftwareManagement { final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); boolean updated = false; - if (sm.getDescription() != null && !sm.getDescription().equals(type.getDescription())) { + if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { type.setDescription(sm.getDescription()); updated = true; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index 18d6b159c..ce7631c26 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -220,21 +220,14 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { SoftwareModuleType newSWType = entityFactory.generateSoftwareModuleType(typeKeyValue, typeNameValue, typeDescValue, assignNumber); newSWType.setColour(colorPicked); - - if (null != typeDescValue) { - newSWType.setDescription(typeDescValue); - } - + newSWType.setDescription(typeDescValue); newSWType.setColour(colorPicked); - newSWType = swTypeManagementService.createSoftwareModuleType(newSWType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newSWType.getName() })); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType)); - } else { uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey")); - } } @@ -244,19 +237,15 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue()); if (null != typeNameValue) { existingType.setName(typeNameValue); - - existingType.setDescription(null != typeDescValue ? typeDescValue : null); - + existingType.setDescription(typeDescValue); existingType.setColour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview())); swTypeManagementService.updateSoftwareModuleType(existingType); uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() })); eventBus.publish(this, new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType)); - } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } - } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 1d2f3b2d4..725ff4b9b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -52,6 +52,7 @@ import com.vaadin.ui.AbstractOrderedLayout; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.CheckBox; import com.vaadin.ui.Component; import com.vaadin.ui.Field; import com.vaadin.ui.GridLayout; @@ -207,6 +208,10 @@ public class CommonDialogWindow extends Window implements Serializable { addListeners(); } + /** + * saves the original values in a Map so we can use them for detecting + * changes + */ public final void setOrginaleValues() { for (final AbstractField field : allComponents) { Object value = field.getValue(); @@ -244,10 +249,13 @@ public class CommonDialogWindow extends Window implements Serializable { private boolean isValuesChanged(final Component currentChangedComponent, final Object newValue) { for (final AbstractField field : allComponents) { - final Object orginalValue = orginalValues.get(field); + Object originalValue = orginalValues.get(field); + if (field instanceof CheckBox && originalValue == null) { + originalValue = Boolean.FALSE; + } final Object currentValue = getCurrentVaue(currentChangedComponent, newValue, field); - if (!isValueEquals(field, orginalValue, currentValue)) { + if (!isValueEquals(field, originalValue, currentValue)) { return true; } } @@ -300,7 +308,15 @@ public class CommonDialogWindow extends Window implements Serializable { requiredComponents.addAll(allComponents.stream().filter(this::hasNullValidator).collect(Collectors.toList())); for (final AbstractField field : requiredComponents) { - final Object value = getCurrentVaue(currentChangedComponent, newValue, field); + Object value = getCurrentVaue(currentChangedComponent, newValue, field); + + if (String.class.equals(field.getType())) { + value = Strings.emptyToNull((String) value); + } + + if (Set.class.equals(field.getType())) { + value = emptyToNull((Collection) value); + } if (value == null) { return false; @@ -319,6 +335,10 @@ public class CommonDialogWindow extends Window implements Serializable { return valid; } + private static Object emptyToNull(final Collection c) { + return (c == null || c.isEmpty()) ? null : c; + } + private boolean hasNullValidator(final Component component) { if (component instanceof AbstractField) { @@ -459,4 +479,18 @@ public class CommonDialogWindow extends Window implements Serializable { } } + /** + * Adds the component manually to the allComponents-List and adds a + * ValueChangeListener to it. Necessary in Update Distribution Type as the + * CheckBox concerned is an ItemProperty... + * + * @param component + * AbstractField + */ + public void updateAllComponents(final AbstractField component) { + + allComponents.add(component); + component.addValueChangeListener(new ChangeListener(component)); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 122599520..2a12bc859 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.ui.distributions.disttype; import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -83,6 +84,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { private IndexedContainer originalSelectedTableContainer; + private Map mandatoryCheckboxMap; + @Override protected void createRequiredComponents() { @@ -315,7 +318,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { saveTblitem = selectedTableContainer.addItem(id); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue( sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue()); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox()); + final CheckBox mandatoryCheckBox = new CheckBox(); + window.updateAllComponents(mandatoryCheckBox); + saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckBox); saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue( sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_DESCRIPTION).getValue()); } @@ -327,7 +332,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { if (sourceTableContainer != null) { Item saveTblitem; saveTblitem = sourceTableContainer.addItem(selectedId); - selectedTable.getContainerDataSource().getItem(selectedId).getItemProperty(DIST_TYPE_NAME); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource() .getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue()); saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(selectedTable.getContainerDataSource() @@ -357,10 +361,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { final SoftwareModuleType swModuleType = softwareManagement.findSoftwareModuleTypeByName(distTypeName); checkMandatoryAndAddMandatoryModuleType(newDistType, isMandatory, swModuleType); } - if (null != typeDescValue) { - newDistType.setDescription(typeDescValue); - } - + newDistType.setDescription(typeDescValue); newDistType.setColour(colorPicked); newDistType = distributionSetManagement.createDistributionSetType(newDistType); uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newDistType.getName() })); @@ -387,7 +388,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { if (null != typeNameValue) { updateDistSetType.setName(typeNameValue); updateDistSetType.setKey(typeKeyValue); - updateDistSetType.setDescription(null != typeDescValue ? typeDescValue : null); + updateDistSetType.setDescription(typeDescValue); if (distributionSetManagement.countDistributionSetsByType(existingType) <= 0 && null != itemIds && !itemIds.isEmpty()) { @@ -407,7 +408,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { .displaySuccess(i18n.get("message.update.success", new Object[] { updateDistSetType.getName() })); eventBus.publish(this, new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType)); - } else { uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); } @@ -417,7 +417,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { final Boolean isMandatory, final SoftwareModuleType swModuleType) { if (isMandatory) { updateDistSetType.addMandatoryModuleType(swModuleType); - } else { updateDistSetType.addOptionalModuleType(swModuleType); } @@ -561,15 +560,15 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { final Item saveTblitem = selectedTableContainer.addItem(swModuleType.getId()); sourceTable.removeItem(swModuleType.getId()); saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); - - // TODO CHECKBOX - final CheckBox mandatoryCheckbox = (CheckBox) selectedTableContainer - .getContainerProperty(swModuleType.getId(), DIST_TYPE_MANDATORY).getValue(); + final CheckBox mandatoryCheckbox = new CheckBox("", mandatory); + mandatoryCheckbox.setId(swModuleType.getName()); + saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox); final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId()); originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName()); - originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory)); + originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox); + + window.updateAllComponents(mandatoryCheckbox); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java index 6527d5db5..8269d4e89 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/layouts/AbstractCreateUpdateTagLayout.java @@ -602,14 +602,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent @Override public void addColorChangeListener(final ColorChangeListener listener) { - // TODO Auto-generated method stub - } @Override public void removeColorChangeListener(final ColorChangeListener listener) { - // TODO Auto-generated method stub - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java index 93c5a4514..2b08c4dbf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java @@ -171,6 +171,13 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { return window; } + public Window getWindow(final String entityId) { + populateValuesOfTarget(entityId); + getWindow(); + window.addStyleName("target-update-window"); + return window; + } + /** * clear all fields of Target Edit Window. */ @@ -203,7 +210,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { /** * @param controllerId */ - public void populateValuesOfTarget(final String controllerId) { + private void populateValuesOfTarget(final String controllerId) { resetComponents(); this.controllerId = controllerId; editTarget = Boolean.TRUE; @@ -214,7 +221,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent { if (target.getDescription() != null) { descTextArea.setValue(target.getDescription()); } - window.addStyleName("target-update-window"); } public FormLayout getFormLayout() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java index ffaa39411..020b29372 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java @@ -106,7 +106,8 @@ public class TargetDetails extends AbstractTableDetailsLayout { if (getSelectedBaseEntity() == null) { return; } - targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId()); + targetAddUpdateWindowLayout.getWindow(getSelectedBaseEntity().getControllerId()); + // targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId()); openWindow(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index f97f8e43f..05eabf249 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -155,14 +155,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { } public CommonDialogWindow getWindow(final Long rolloutId) { - resetComponents(); - window = SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, - SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null, - uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); + window = getWindow(); populateData(rolloutId); return window; } + public CommonDialogWindow getWindow() { + resetComponents(); + return SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null, + SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null, + uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n); + } + /** * Reset the field values. */ @@ -610,9 +614,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { @Override public void validate(final Object value) { try { - if (HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null - || (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null - && targetFilterQuery.getValue() == null)) { + if (isNoOfGroupsOrTargetFilterEmpty()) { uiNotification .displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing")); } else { @@ -626,14 +628,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch ( - - @SuppressWarnings("squid:S1166") final InvalidValueException ex) { + catch (final InvalidValueException ex) { // we have to throw the exception here, otherwise the UI won't // show the vaadin validation error! throw ex; } } + + private boolean isNoOfGroupsOrTargetFilterEmpty() { + return HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null + || (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null + && targetFilterQuery.getValue() == null); + } } private int getGroupSize() { @@ -654,7 +660,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { + catch (final InvalidValueException ex) { // we have to throw the exception here, otherwise the UI won't // show the vaadin validation error! throw ex; @@ -676,7 +682,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { // suppress the need of preserve original exception, will blow // up the // log and not necessary here - catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) { + catch (final InvalidValueException ex) { // we have to throw the exception here, otherwise the UI won't // show the vaadin validation error! throw ex; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java index 49bb90100..81608d42d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListHeader.java @@ -91,7 +91,7 @@ public class RolloutListHeader extends AbstractGridHeader { @Override protected void addNewItem(final ClickEvent event) { - final Window addTargetWindow = addUpdateRolloutWindow.getWindow(null); + final Window addTargetWindow = addUpdateRolloutWindow.getWindow(); UI.getCurrent().addWindow(addTargetWindow); addTargetWindow.setVisible(Boolean.TRUE); From 11f9b6737e3f91926b135ddc216f12298e3f6daf Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 30 Jun 2016 18:06:08 +0200 Subject: [PATCH 76/82] Added Ids for components Signed-off-by: Melanie Retter --- .../eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java | 1 + .../hawkbit/ui/management/tag/SpColorPickerPreview.java | 4 +++- .../eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java index 732523560..2c6191bc8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerLayout.java @@ -73,6 +73,7 @@ public class ColorPickerLayout extends GridLayout { colorSelect.setWidth("220px"); redSlider = createRGBSlider("", "red"); + redSlider.setId(SPUIComponentIdProvider.COLOR_PICKER_RED_SLIDER); greenSlider = createRGBSlider("", "green"); blueSlider = createRGBSlider("", "blue"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java index 29db56009..afbed85a6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/SpColorPickerPreview.java @@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.management.tag; import java.lang.reflect.Field; +import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; + import com.google.common.base.Throwables; import com.vaadin.data.Property; import com.vaadin.data.Property.ValueChangeEvent; @@ -44,7 +46,7 @@ public final class SpColorPickerPreview extends ColorPickerPreview implements Te try { final Field textField = ColorPickerPreview.class.getDeclaredField("field"); textField.setAccessible(true); - ((TextField) textField.get(this)).setId("color-preview-field"); + ((TextField) textField.get(this)).setId(SPUIComponentIdProvider.COLOR_PREVIEW_FIELD); ((TextField) textField.get(this)).addTextChangeListener(this); } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { Throwables.propagate(e); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index 7a7d62b87..826985162 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -310,6 +310,14 @@ public final class SPUIComponentIdProvider { * Id for ColorPickerLayout */ public static final String COLOR_PICKER_LAYOUT = "color.picker.layout"; + /** + * Id for ColorPickerLayout's red slider + */ + public static final String COLOR_PICKER_RED_SLIDER = "color.picker.red.slider"; + /** + * Id for Color preview field with the color code + */ + public static final String COLOR_PREVIEW_FIELD = "color-preview-field"; /** * Id for OptionGroup Create/Update tag */ From a4252283dbc8f408525639f95930126b9fbcade8 Mon Sep 17 00:00:00 2001 From: kaizimmerm Date: Fri, 1 Jul 2016 08:42:17 +0200 Subject: [PATCH 77/82] Target securityToken and address fully manageable through MGMT API. Signed-off-by: kaizimmerm --- .../model/target/MgmtTargetRequestBody.java | 11 ++++ .../mgmt/rest/resource/MgmtTargetMapper.java | 3 +- .../rest/resource/MgmtTargetResource.java | 7 +++ .../rest/resource/MgmtTargetResourceTest.java | 56 ++++++++++++++++++- .../hawkbit/repository/EntityFactory.java | 14 +++++ .../hawkbit/repository/model/Target.java | 6 ++ .../repository/jpa/JpaEntityFactory.java | 9 +++ .../repository/jpa/model/JpaTarget.java | 14 ++++- .../repository/jpa/TargetManagementTest.java | 8 +-- .../hawkbit/rest/util/JsonBuilder.java | 10 ++-- 10 files changed, 124 insertions(+), 14 deletions(-) diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java index b9c0b001a..f7a297be1 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/target/MgmtTargetRequestBody.java @@ -21,6 +21,17 @@ public class MgmtTargetRequestBody { @JsonProperty private String address; + @JsonProperty + private String securityToken; + + public String getSecurityToken() { + return securityToken; + } + + public void setSecurityToken(final String securityToken) { + this.securityToken = securityToken; + } + /** * @return the name */ diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index f6cf9f54b..a889edc35 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -182,10 +182,11 @@ public final class MgmtTargetMapper { } static Target fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) { - final Target target = entityFactory.generateTarget(targetRest.getControllerId()); + final Target target = entityFactory.generateTarget(targetRest.getControllerId(), targetRest.getSecurityToken()); target.setDescription(targetRest.getDescription()); target.setName(targetRest.getName()); target.getTargetInfo().setAddress(targetRest.getAddress()); + return target; } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java index c41dadd27..5ddb74314 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java @@ -125,6 +125,13 @@ public class MgmtTargetResource implements MgmtTargetRestApi { if (targetRest.getName() != null) { existingTarget.setName(targetRest.getName()); } + if (targetRest.getAddress() != null) { + existingTarget.getTargetInfo().setAddress(targetRest.getAddress()); + } + if (targetRest.getSecurityToken() != null) { + existingTarget.setSecurityToken(targetRest.getSecurityToken()); + } + final Target updateTarget = this.targetManagement.updateTarget(existingTarget); return new ResponseEntity<>(MgmtTargetMapper.toResponse(updateTarget), HttpStatus.OK); diff --git a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index ed6ee4a93..a528438bb 100644 --- a/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -355,6 +355,54 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy); } + @Test + @Description("Ensures that target update request is reflected by repository.") + public void updateTargetSecurityToken() throws Exception { + final String knownControllerId = "123"; + final String knownNewToken = "6567576565"; + final String knownNameNotModiy = "nameNotModiy"; + final String body = new JSONObject().put("securityToken", knownNewToken).toString(); + + // prepare + final Target t = entityFactory.generateTarget(knownControllerId); + t.setName(knownNameNotModiy); + targetManagement.createTarget(t); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.securityToken", equalTo(knownNewToken))) + .andExpect(jsonPath("$.name", equalTo(knownNameNotModiy))); + + final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownControllerId); + assertThat(findTargetByControllerID.getSecurityToken()).isEqualTo(knownNewToken); + assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy); + } + + @Test + @Description("Ensures that target update request is reflected by repository.") + public void updateTargetAddress() throws Exception { + final String knownControllerId = "123"; + final String knownNewAddress = "amqp://test123/foobar"; + final String knownNameNotModiy = "nameNotModiy"; + final String body = new JSONObject().put("address", knownNewAddress).toString(); + + // prepare + final Target t = entityFactory.generateTarget(knownControllerId); + t.setName(knownNameNotModiy); + targetManagement.createTarget(t); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) + .andExpect(jsonPath("$.name", equalTo(knownNameNotModiy))); + + final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownControllerId); + assertThat(findTargetByControllerID.getTargetInfo().getAddress().toString()).isEqualTo(knownNewAddress); + assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy); + } + @Test @Description("Ensures that target query returns list of targets in defined format.") public void getTargetWithoutAddtionalRequestParameters() throws Exception { @@ -679,7 +727,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { @Test public void createTargetsListReturnsSuccessful() throws Exception { - final Target test1 = entityFactory.generateTarget("id1"); + final Target test1 = entityFactory.generateTarget("id1", "token"); test1.setDescription("testid1"); test1.setName("testname1"); test1.getTargetInfo().setAddress("amqp://test123/foobar"); @@ -696,7 +744,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { targets.add(test3); final MvcResult mvcResult = mvc - .perform(post("/rest/v1/targets/").content(JsonBuilder.targets(targets)) + .perform(post("/rest/v1/targets/").content(JsonBuilder.targets(targets, true)) .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) @@ -705,6 +753,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { .andExpect(jsonPath("[0].description", equalTo("testid1"))) .andExpect(jsonPath("[0].createdAt", not(equalTo(0)))) .andExpect(jsonPath("[0].createdBy", equalTo("bumlux"))) + .andExpect(jsonPath("[0].securityToken", equalTo("token"))) .andExpect(jsonPath("[0].address", equalTo("amqp://test123/foobar"))) .andExpect(jsonPath("[1].name", equalTo("testname2"))) .andExpect(jsonPath("[1].createdBy", equalTo("bumlux"))) @@ -731,6 +780,9 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest { assertThat(targetManagement.findTargetByControllerID("id1")).isNotNull(); assertThat(targetManagement.findTargetByControllerID("id1").getName()).isEqualTo("testname1"); assertThat(targetManagement.findTargetByControllerID("id1").getDescription()).isEqualTo("testid1"); + assertThat(targetManagement.findTargetByControllerID("id1").getSecurityToken()).isEqualTo("token"); + assertThat(targetManagement.findTargetByControllerID("id1").getTargetInfo().getAddress().toString()) + .isEqualTo("amqp://test123/foobar"); assertThat(targetManagement.findTargetByControllerID("id2")).isNotNull(); assertThat(targetManagement.findTargetByControllerID("id2").getName()).isEqualTo("testname2"); assertThat(targetManagement.findTargetByControllerID("id2").getDescription()).isEqualTo("testid2"); diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java index 7542cd2ce..87919729e 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/EntityFactory.java @@ -287,6 +287,7 @@ public interface EntityFactory { /** * Generates an empty {@link Target} without persisting it. + * {@link Target#getSecurityToken()} is generated. * * @param controllerID * of the {@link Target} @@ -295,6 +296,19 @@ public interface EntityFactory { */ Target generateTarget(@NotEmpty String controllerID); + /** + * Generates an empty {@link Target} without persisting it. + * + * @param controllerID + * of the {@link Target} + * @param securityToken + * of the {@link Target} for authentication if enabled on tenant. + * Generates one if empty or null. + * + * @return {@link Target} object + */ + Target generateTarget(@NotEmpty String controllerID, @NotEmpty String securityToken); + /** * Generates an empty {@link TargetFilterQuery} without persisting it. * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java index 56ab89ad3..c09b28a2f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/Target.java @@ -58,4 +58,10 @@ public interface Target extends NamedEntity { */ String getSecurityToken(); + /** + * @param token + * new securityToken + */ + void setSecurityToken(String token); + } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java index a3792de54..51b59f08f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaEntityFactory.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa; import java.util.Collection; +import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; @@ -87,6 +88,14 @@ public class JpaEntityFactory implements EntityFactory { return new JpaTarget(controllerId); } + @Override + public Target generateTarget(final String controllerId, final String securityToken) { + if (StringUtils.isEmpty(securityToken)) { + return new JpaTarget(controllerId); + } + return new JpaTarget(controllerId, securityToken); + } + @Override public TargetTag generateTargetTag() { return new JpaTargetTag(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 94f50ff0d..183405470 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -115,9 +115,21 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable targets) { + public static String targets(final List targets, final boolean withToken) { final StringBuilder builder = new StringBuilder(); builder.append("["); @@ -381,10 +377,12 @@ public abstract class JsonBuilder { final String address = target.getTargetInfo().getAddress() != null ? target.getTargetInfo().getAddress().toString() : null; + final String token = withToken ? target.getSecurityToken() : null; + builder.append(new JSONObject().put("controllerId", target.getControllerId()) .put("description", target.getDescription()).put("name", target.getName()).put("createdAt", "0") .put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh") - .put("address", address).toString()); + .put("address", address).put("securityToken", token).toString()); } catch (final Exception e) { e.printStackTrace(); } From f2fc1aa91ac548ec63c2db21bb02d5dc8a07708f Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Fri, 1 Jul 2016 16:40:07 +0200 Subject: [PATCH 78/82] Simulator throughpout improvements. Signed-off-by: Kai Zimmermann --- .../simulator/DeviceSimulatorUpdater.java | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index 81237beb7..69ed4fd4a 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -10,8 +10,6 @@ package org.eclipse.hawkbit.simulator; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.security.DigestOutputStream; import java.security.KeyManagementException; @@ -34,6 +32,7 @@ import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.eclipse.hawkbit.dmf.json.model.Artifact; +import org.eclipse.hawkbit.dmf.json.model.Artifact.UrlProtocol; import org.eclipse.hawkbit.dmf.json.model.SoftwareModule; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus; @@ -59,7 +58,7 @@ import com.google.common.io.ByteStreams; public class DeviceSimulatorUpdater { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceSimulatorUpdater.class); - private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(4); + private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(8); @Autowired private SpSenderService spSenderService; @@ -198,18 +197,14 @@ public class DeviceSimulatorUpdater { private static void handleArtifacts(final String targetToken, final List status, final Artifact artifact) { - artifact.getUrls().entrySet().forEach(entry -> { - switch (entry.getKey()) { - case HTTP: - case HTTPS: - status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1(), - artifact.getSize())); - break; - default: - // not supported yet - break; - } - }); + + if (artifact.getUrls().containsKey(UrlProtocol.HTTPS)) { + status.add(downloadUrl(artifact.getUrls().get(UrlProtocol.HTTPS), targetToken, + artifact.getHashes().getSha1(), artifact.getSize())); + } else if (artifact.getUrls().containsKey(UrlProtocol.HTTP)) { + status.add(downloadUrl(artifact.getUrls().get(UrlProtocol.HTTP), targetToken, + artifact.getHashes().getSha1(), artifact.getSize())); + } } private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash, @@ -236,22 +231,15 @@ public class DeviceSimulatorUpdater { return new UpdateStatus(ResponseStatus.ERROR, message); } - final File tempFile = File.createTempFile("uploadFile", null); - // Exception squid:S2070 - not used for hashing sensitive // data @SuppressWarnings("squid:S2070") final MessageDigest md = MessageDigest.getInstance("SHA-1"); - try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) { - try (final BufferedOutputStream bdos = new BufferedOutputStream(dos)) { - try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { - overallread = ByteStreams.copy(bis, bdos); - } - } - } finally { - if (tempFile != null && !tempFile.delete()) { - LOGGER.error("Could not delete temporary file: {}", tempFile); + try (final BufferedOutputStream bdos = new BufferedOutputStream( + new DigestOutputStream(ByteStreams.nullOutputStream(), md))) { + try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { + overallread = ByteStreams.copy(bis, bdos); } } From 21bd2c33ace92acc20056524b4d1cf0f8e7f62f7 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 7 Jul 2016 16:45:07 +0200 Subject: [PATCH 79/82] Add IS_SYSTEM_CODE to all springEvalExpr and remove explicit usage Signed-off-by: Michael Hirsch --- .../repository/DeploymentManagement.java | 6 +- .../hawkbit/repository/RolloutManagement.java | 15 +- .../hawkbit/repository/SystemManagement.java | 10 +- .../TenantConfigurationManagement.java | 12 +- .../im/authentication/SpPermission.java | 133 +++++++++++------- 5 files changed, 96 insertions(+), 80 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 9dc5f74c8..270de3e74 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -269,8 +269,7 @@ public interface DeploymentManagement { * @return the actions referring a specific rollout and a specific parent * rollout group in a specific status */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) List findActionsByRolloutGroupParentAndStatus(@NotNull Rollout rollout, @NotNull RolloutGroup rolloutGroupParent, @NotNull Action.Status actionStatus); @@ -496,8 +495,7 @@ public interface DeploymentManagement { * the action to start now. * @return the action which has been started */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) Action startScheduledAction(@NotNull Action action); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index 2c6e85dda..337475318 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -61,8 +61,7 @@ public interface RolloutManagement { * this check. This check is only applied if the last check is * less than (lastcheck-delay). */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) void checkRunningRollouts(long delayBetweenChecks); /** @@ -266,8 +265,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#RUNNING}. * Only running rollouts can be paused. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) void pauseRollout(@NotNull Rollout rollout); /** @@ -281,8 +279,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#PAUSED}. Only * paused rollouts can be resumed. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) void resumeRollout(@NotNull Rollout rollout); /** @@ -303,8 +300,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) Rollout startRollout(@NotNull Rollout rollout); /** @@ -326,8 +322,7 @@ public interface RolloutManagement { * if given rollout is not in {@link RolloutStatus#READY}. Only * ready rollouts can be started. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE) Rollout startRolloutAsync(@NotNull Rollout rollout); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 039e4ae13..a44b13d92 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -39,16 +39,14 @@ public interface SystemManagement { * @param tenant * to delete */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) void deleteTenant(@NotNull String tenant); /** * * @return list of all tenant names in the system. */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) List findTenants(); /** @@ -68,8 +66,8 @@ public interface SystemManagement { /** * Returns {@link TenantMetaData} of given and current tenant. Creates for * new tenants also two {@link SoftwareModuleType} (os and app) and - * {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} {@link DistributionSetType}s - * (os and os_app). + * {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} + * {@link DistributionSetType}s (os and os_app). * * DISCLAIMER: this variant is used during initial login (where the tenant * is not yet in the session). Please user {@link #getTenantMetadata()} for diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 734704f05..9c467f9dd 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -54,8 +54,7 @@ public interface TenantConfigurationManagement { * @return if no default value is set and no database value available * or returns the tenant configuration value */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantConfigurationValue buildTenantConfigurationValueByKey(TenantConfigurationKey configurationKey, Class propertyType, TenantConfiguration tenantConfiguration); @@ -87,8 +86,7 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantConfigurationValue getConfigurationValue(TenantConfigurationKey configurationKey); /** @@ -114,8 +112,7 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantConfigurationValue getConfigurationValue(TenantConfigurationKey configurationKey, Class propertyType); @@ -139,7 +136,6 @@ public interface TenantConfigurationManagement { * if the property cannot be converted to the given * {@code propertyType} */ - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_SYSTEM_CODE) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) T getGlobalConfigurationValue(TenantConfigurationKey configurationKey, Class propertyType); } diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index 139954538..aace01248 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -224,8 +224,10 @@ public final class SpPermission { /* * Spring security eval expressions. */ - private static final String HAS_AUTH_PREFIX = "hasAuthority('"; - private static final String HAS_AUTH_SUFFIX = "')"; + private static final String BRACKET_OPEN = "("; + private static final String BRACKET_CLOSE = ")"; + private static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'"; + private static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE; private static final String HAS_AUTH_AND = " and "; /** @@ -258,81 +260,109 @@ public final class SpPermission { public static final String HAS_AUTH_OR = " or "; /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#UPDATE_TARGET}. + * Spring security eval hasAnyRole expression to check if the spring + * context contains system code role + * {@link SpringEvalExpressions#SYSTEM_ROLE}. */ - public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX; + public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#SYSTEM_ADMIN}. + * context contains {@link SpPermission#UPDATE_TARGET} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_TARGET}. + * context contains {@link SpPermission#SYSTEM_ADMIN} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE;; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_TARGET}. + * context contains {@link SpPermission#READ_TARGET} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR + + IS_SYSTEM_CODE;; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DELETE_TARGET}. + * context contains {@link SpPermission#CREATE_TARGET} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#DELETE_TARGET} or + * {@link #IS_SYSTEM_CODE}. + */ + public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE;; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#READ_REPOSITORY} and - * {@link SpPermission#UPDATE_TARGET}. + * {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_REPOSITORY}. + * context contains {@link SpPermission#CREATE_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DELETE_REPOSITORY}. + * context contains {@link SpPermission#DELETE_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_REPOSITORY}. + * context contains {@link SpPermission#READ_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#UPDATE_REPOSITORY}. + * context contains {@link SpPermission#UPDATE_REPOSITORY} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#READ_REPOSITORY} and - * {@link SpPermission#READ_TARGET}. + * {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT}. + * context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT} or + * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT - + HAS_AUTH_SUFFIX; + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAnyRole expression to check if the spring @@ -350,57 +380,56 @@ public final class SpPermission { public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE + HAS_AUTH_SUFFIX; - /** - * Spring security eval hasAnyRole expression to check if the spring - * context contains system code role - * {@link SpringEvalExpressions#SYSTEM_ROLE}. - */ - public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX; - /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#CREATE_REPOSITORY} and - * {@link SpPermission#CREATE_TARGET}. + * {@link SpPermission#CREATE_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_REPOSITORY - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + CREATE_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} + * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} or + * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT - + HAS_AUTH_SUFFIX; + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and - * {@link SpPermission#READ_TARGET} + * {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = HAS_AUTH_PREFIX - + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET - + HAS_AUTH_SUFFIX;; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX + + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and - * {@link SpPermission#UPDATE_TARGET}. + * {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT - + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = BRACKET_OPEN + HAS_AUTH_PREFIX + + ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + + HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#TENANT_CONFIGURATION} + * context contains {@link SpPermission#TENANT_CONFIGURATION} or + * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION - + HAS_AUTH_SUFFIX; + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#SYSTEM_MONITOR} + * context contains {@link SpPermission#SYSTEM_MONITOR} or + * {@link #IS_SYSTEM_CODE}. */ - public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX + + HAS_AUTH_OR + IS_SYSTEM_CODE; private SpringEvalExpressions() { // utility class From c3586b02303570306a15cacc0ac557522a3f7cfb Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 8 Jul 2016 10:20:37 +0200 Subject: [PATCH 80/82] remove double ended semicolon Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/im/authentication/SpPermission.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index aace01248..7d52b7a01 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -280,7 +280,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring @@ -288,7 +288,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR - + IS_SYSTEM_CODE;; + + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring @@ -296,7 +296,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring @@ -304,7 +304,7 @@ public final class SpPermission { * {@link #IS_SYSTEM_CODE}. */ public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE;; + + HAS_AUTH_OR + IS_SYSTEM_CODE; /** * Spring security eval hasAuthority expression to check if spring From d0cf8a40bd3de778db14327c5416397526c1726d Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 8 Jul 2016 13:32:02 +0200 Subject: [PATCH 81/82] fix javadoc link Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/im/authentication/SpPermission.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index 7d52b7a01..daf5f0dd9 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -367,7 +367,7 @@ public final class SpPermission { /** * Spring security eval hasAnyRole expression to check if the spring * context contains the anoynmous role or the controller specific role - * {@link SpPermission#CONTROLLER_ROLE}. + * {@link SpringEvalExpressions#CONTROLLER_ROLE}. */ public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE + "')"; @@ -375,7 +375,7 @@ public final class SpPermission { /** * Spring security eval hasAuthority expression to check if the spring * context contains the role to allow controllers to download specific - * role {@link SpPermission#CONTROLLER_DOWNLOAD_ROLE}. + * role {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE} */ public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE + HAS_AUTH_SUFFIX; From 2f9a9b456d43ee9aec67286024e27b0e12a717bf Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 13 Jul 2016 08:41:59 +0200 Subject: [PATCH 82/82] fix sonar critical issues Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/ui/common/CommonDialogWindow.java | 2 +- .../filterlayout/AbstractFilterMultiButtonClick.java | 3 ++- .../eclipse/hawkbit/ui/common/table/AbstractTable.java | 3 --- .../hawkbit/ui/common/tagdetails/AbstractTagToken.java | 8 ++------ .../ui/distributions/dstable/DistributionSetDetails.java | 2 +- .../ui/management/targettable/TargetBeanQuery.java | 2 +- 6 files changed, 7 insertions(+), 13 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java index 725ff4b9b..a6b05e0a5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/CommonDialogWindow.java @@ -96,7 +96,7 @@ public class CommonDialogWindow extends Window implements Serializable { private final ClickListener close = event -> close(); - private final Map orginalValues; + private final transient Map orginalValues; private final List> allComponents; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java index 8b3ac4cde..f7d3656b1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/filterlayout/AbstractFilterMultiButtonClick.java @@ -22,7 +22,8 @@ import com.vaadin.ui.Button.ClickEvent; */ public abstract class AbstractFilterMultiButtonClick extends AbstractFilterButtonClickBehaviour { - protected final Set