From ee1aabc93fa06628996ae98f7a4ce76f08f2a978 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 22 Dec 2015 16:30:00 +0100 Subject: [PATCH 01/42] Added subview for polling configuration in system configuration window * updated architectural concept os subview ** added base class BaseConfigurationView ** updated interface ConfigurationGroup * updated message strings for new pollign configurations * implemented new vaadin compontent DurationField (extends DateTimeField) TODO: * update positioning of DurationFields * update validation of user input, espacilly against min and max value Signed-off-by: Nonnenmacher Fabian --- .../AuthenticationConfigurationView.java | 73 ++++----- .../BaseConfigurationView.java | 35 +++++ .../ConfigurationGroup.java | 13 +- .../DefaultDistributionSetTypeLayout.java | 17 +-- .../PollingConfigurationView.java | 144 ++++++++++++++++++ .../TenantConfigurationDashboardView.java | 62 ++++++-- .../polling/DurationField.java | 96 ++++++++++++ .../src/main/resources/messages.properties | 6 +- .../src/main/resources/messages_en.properties | 3 + 9 files changed, 371 insertions(+), 78 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java index c7fa7c72b..ea228bbc7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java @@ -8,9 +8,6 @@ */ package org.eclipse.hawkbit.ui.tenantconfiguration; -import java.util.ArrayList; -import java.util.List; - import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -26,7 +23,6 @@ import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.CheckBox; -import com.vaadin.ui.CustomComponent; import com.vaadin.ui.GridLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; @@ -40,8 +36,8 @@ import com.vaadin.ui.VerticalLayout; */ @SpringComponent @ViewScope -public class AuthenticationConfigurationView extends CustomComponent - implements ConfigurationGroup, TenantConfigurationItem.TenantConfigurationChangeListener { +public class AuthenticationConfigurationView extends BaseConfigurationView + implements ConfigurationGroup, TenantConfigurationItem.TenantConfigurationChangeListener, ValueChangeListener { /** * @@ -65,8 +61,6 @@ public class AuthenticationConfigurationView extends CustomComponent @Autowired private GatewaySecurityTokenAuthenticationConfigurationItem gatewaySecurityTokenAuthenticationConfigurationItem; - private final List configurationChangeListeners = new ArrayList<>(); - private CheckBox gatewaySecTokenCheckBox; private CheckBox targetSecTokenCheckBox; @@ -100,16 +94,14 @@ public class AuthenticationConfigurationView extends CustomComponent certificateAuthCheckbox = SPUIComponentProvider.getCheckBox("", DIST_CHECKBOX_STYLE, null, false, ""); certificateAuthCheckbox.setValue(certificateAuthenticationConfigurationItem.isConfigEnabled()); - certificateAuthCheckbox.addValueChangeListener(new AuthenticationTenantConfigurationItemChangeListener( - certificateAuthCheckbox, certificateAuthenticationConfigurationItem)); + certificateAuthCheckbox.addValueChangeListener(this); certificateAuthenticationConfigurationItem.addConfigurationChangeListener(this); gridLayout.addComponent(certificateAuthCheckbox, 0, 0); gridLayout.addComponent(certificateAuthenticationConfigurationItem, 1, 0); targetSecTokenCheckBox = SPUIComponentProvider.getCheckBox("", DIST_CHECKBOX_STYLE, null, false, ""); targetSecTokenCheckBox.setValue(targetSecurityTokenAuthenticationConfigurationItem.isConfigEnabled()); - targetSecTokenCheckBox.addValueChangeListener(new AuthenticationTenantConfigurationItemChangeListener( - targetSecTokenCheckBox, targetSecurityTokenAuthenticationConfigurationItem)); + targetSecTokenCheckBox.addValueChangeListener(this); targetSecurityTokenAuthenticationConfigurationItem.addConfigurationChangeListener(this); gridLayout.addComponent(targetSecTokenCheckBox, 0, 1); gridLayout.addComponent(targetSecurityTokenAuthenticationConfigurationItem, 1, 1); @@ -117,8 +109,7 @@ public class AuthenticationConfigurationView extends CustomComponent gatewaySecTokenCheckBox = SPUIComponentProvider.getCheckBox("", DIST_CHECKBOX_STYLE, null, false, ""); gatewaySecTokenCheckBox.setId("gatewaysecuritycheckbox"); gatewaySecTokenCheckBox.setValue(gatewaySecurityTokenAuthenticationConfigurationItem.isConfigEnabled()); - gatewaySecTokenCheckBox.addValueChangeListener(new AuthenticationTenantConfigurationItemChangeListener( - gatewaySecTokenCheckBox, gatewaySecurityTokenAuthenticationConfigurationItem)); + gatewaySecTokenCheckBox.addValueChangeListener(this); gatewaySecurityTokenAuthenticationConfigurationItem.addConfigurationChangeListener(this); gridLayout.addComponent(gatewaySecTokenCheckBox, 0, 2); gridLayout.addComponent(gatewaySecurityTokenAuthenticationConfigurationItem, 1, 2); @@ -126,7 +117,6 @@ public class AuthenticationConfigurationView extends CustomComponent vLayout.addComponent(gridLayout); rootPanel.setContent(vLayout); setCompositionRoot(rootPanel); - } /* @@ -160,47 +150,42 @@ public class AuthenticationConfigurationView extends CustomComponent gatewaySecTokenCheckBox.setValue(gatewaySecurityTokenAuthenticationConfigurationItem.isConfigEnabled()); } - private void notifyConfigurationChanged() { - configurationChangeListeners.forEach(listener -> listener.configurationChanged()); - } - - @Override - public void addChangeListener(final ConfigurationGroupChangeListener listener) { - configurationChangeListeners.add(listener); - } - @Override public void configurationHasChanged() { notifyConfigurationChanged(); } - private final class AuthenticationTenantConfigurationItemChangeListener implements ValueChangeListener { + /* + * (non-Javadoc) + * + * @see com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin. + * data.Property. ValueChangeEvent) + */ + @Override + public void valueChange(final ValueChangeEvent event) { - private static final long serialVersionUID = 1L; - private final CheckBox checkBox; - private final TenantConfigurationItem configurationItem; - - private AuthenticationTenantConfigurationItemChangeListener(final CheckBox checkBox, - final TenantConfigurationItem configurationItem) { - this.checkBox = checkBox; - this.configurationItem = configurationItem; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin. - * data.Property. ValueChangeEvent) - */ - @Override - public void valueChange(final ValueChangeEvent event) { + if (event.getProperty() instanceof CheckBox) { notifyConfigurationChanged(); + + CheckBox checkBox = (CheckBox) event.getProperty(); + TenantConfigurationItem configurationItem = null; + + if (checkBox == gatewaySecTokenCheckBox) { + configurationItem = gatewaySecurityTokenAuthenticationConfigurationItem; + } else if (checkBox == targetSecTokenCheckBox) { + configurationItem = targetSecurityTokenAuthenticationConfigurationItem; + } else if (checkBox == certificateAuthCheckbox) { + configurationItem = certificateAuthenticationConfigurationItem; + } else { + return; + } + if (checkBox.getValue()) { configurationItem.configEnable(); } else { configurationItem.configDisable(); } + } } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java new file mode 100644 index 000000000..11cc7d2a6 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java @@ -0,0 +1,35 @@ +package org.eclipse.hawkbit.ui.tenantconfiguration; + +import java.util.ArrayList; +import java.util.List; + +import com.vaadin.ui.CustomComponent; + +/** + * base class for all configuration views. This class implements the logic for + * the handling of the + * + * @author Fabian Nonnenmacher + */ +public abstract class BaseConfigurationView extends CustomComponent implements ConfigurationGroup { + + private static final long serialVersionUID = 1L; + + private final List configurationChangeListeners = new ArrayList<>(); + + protected void notifyConfigurationChanged() { + configurationChangeListeners.forEach(listener -> listener.configurationChanged()); + } + + @Override + public void addChangeListener(final ConfigurationGroupChangeListener listener) { + configurationChangeListeners.add(listener); + } + + @Override + public boolean isUserInputValid() { + // default return value is true, because often user can only choose from + // different valid options. + return true; + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java index cfe85cae3..60f1934f9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java @@ -10,12 +10,14 @@ package org.eclipse.hawkbit.ui.tenantconfiguration; import java.io.Serializable; +import com.vaadin.ui.Component; + /** * * * */ -public interface ConfigurationGroup { +public interface ConfigurationGroup extends Component { /** * called to store any configuration changes. @@ -27,6 +29,13 @@ public interface ConfigurationGroup { */ void undo(); + /** + * called to verify that the Input done by the user is valid + * + * @return true when the data is valid, false otherwise + */ + boolean isUserInputValid(); + /** * Adds a configuration change listener to notify about configuration * changes. @@ -40,8 +49,6 @@ public interface ConfigurationGroup { /** * Configuration Change Listener to be notified about configuration changes * in configuration group. - * - * * */ interface ConfigurationGroupChangeListener extends Serializable { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/DefaultDistributionSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/DefaultDistributionSetTypeLayout.java index 173ca5f9e..ec0e643de 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/DefaultDistributionSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/DefaultDistributionSetTypeLayout.java @@ -8,9 +8,6 @@ */ package org.eclipse.hawkbit.ui.tenantconfiguration; -import java.util.ArrayList; -import java.util.List; - import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -29,7 +26,6 @@ import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.Alignment; import com.vaadin.ui.ComboBox; -import com.vaadin.ui.CustomComponent; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; @@ -43,7 +39,7 @@ import com.vaadin.ui.VerticalLayout; */ @SpringComponent @ViewScope -public class DefaultDistributionSetTypeLayout extends CustomComponent implements ConfigurationGroup { +public class DefaultDistributionSetTypeLayout extends BaseConfigurationView implements ConfigurationGroup { private static final long serialVersionUID = 17896542758L; @@ -66,8 +62,6 @@ public class DefaultDistributionSetTypeLayout extends CustomComponent implements private Label changeIcon; - private final List configurationChangeListeners = new ArrayList<>(); - /** * Initialize Default Distribution Set layout. */ @@ -163,13 +157,4 @@ public class DefaultDistributionSetTypeLayout extends CustomComponent implements changeIcon.setVisible(false); } } - - private void notifyConfigurationChanged() { - configurationChangeListeners.forEach(listener -> listener.configurationChanged()); - } - - @Override - public void addChangeListener(final ConfigurationGroupChangeListener listener) { - configurationChangeListeners.add(listener); - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java new file mode 100644 index 000000000..3a5fb92a0 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -0,0 +1,144 @@ +package org.eclipse.hawkbit.ui.tenantconfiguration; + +import static org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper.EXPECTED_POLLING_TIME_FORMAT; + +import javax.annotation.PostConstruct; + +import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; +import org.eclipse.hawkbit.ui.tenantconfiguration.polling.DurationField; +import org.eclipse.hawkbit.ui.utils.I18N; +import org.springframework.beans.factory.annotation.Autowired; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Validator; +import com.vaadin.spring.annotation.SpringComponent; +import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.Field; +import com.vaadin.ui.Label; +import com.vaadin.ui.Panel; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; + +/** + * View to configure the polling interval and the overdue time. + * + * @author Fabian Nonnenmacher + * + */ +@SpringComponent +@ViewScope +public class PollingConfigurationView extends BaseConfigurationView + implements ConfigurationGroup, Field.ValueChangeListener { + + private static final long serialVersionUID = 1L; + + @Autowired + private transient SystemManagement systemManagement; + + @Autowired + private I18N i18n; + + @Autowired + PollConfigurationHelper pollConfigurationHelper; + + final private DurationField fieldPollingTime = new DurationField(); + final private DurationField fieldPollingOverdueTime = new DurationField(); + + /** + * Initialize Authentication Configuration layout. + */ + @PostConstruct + public void init() { + + Validator correctFormatValidator = new Validator() { + private static final long serialVersionUID = 1L; + + @Override + public void validate(Object value) throws InvalidValueException { + if (!(value instanceof String) || !((String) value).matches(EXPECTED_POLLING_TIME_FORMAT)) { + throw new InvalidValueException("Not in HH:MM:SS Format."); + } + } + }; + + final Panel rootPanel = new Panel(); + rootPanel.setSizeFull(); + + rootPanel.addStyleName("config-panel"); + + // TODO Better Layout than Vertical Layout - maybe a table layout? + final VerticalLayout vLayout = new VerticalLayout(); + vLayout.setMargin(true); + vLayout.setSizeFull(); + + final Label headerDisSetType = new Label(i18n.get("configuration.polling.title")); + headerDisSetType.addStyleName("config-panel-header"); + vLayout.addComponent(headerDisSetType); + + final Label labelPollingTime = new Label(i18n.get("configuration.polling.time")); + vLayout.addComponent(labelPollingTime); + + vLayout.addComponent(fieldPollingTime); + + final Label labelPollingOverdueTime = new Label(i18n.get("configuration.polling.overduetime")); + vLayout.addComponent(labelPollingOverdueTime); + + vLayout.addComponent(fieldPollingOverdueTime); + + rootPanel.setContent(vLayout); + setCompositionRoot(rootPanel); + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin.data. + * Property.ValueChangeEvent) + * + * This method is called when a value of a textField changes. When the value + * is not in the correct format, but has valid data, this method will change + * the value to the correct format + */ + @Override + public void valueChange(ValueChangeEvent event) { + + notifyConfigurationChanged(); + + if (event.getProperty() instanceof TextField) { + TextField textfield = (TextField) event.getProperty(); + + String value = textfield.getValue(); + + if (value.matches("[0-9]{1,6}")) { + value = "000000".substring(value.length()) + value; + value = value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6); + } + + if (value.matches("([0-5]?[0-9]?(:[0-5][0-9]){1,2})")) { + value = "00:00:00".substring(0, 8 - value.length()) + value; + } + + if (value.matches(EXPECTED_POLLING_TIME_FORMAT)) { + textfield.setValue(value); + } + } + } + + @Override + public void save() { + // TODO Auto-generated method stub + } + + @Override + public void undo() { + + } + + @Override + public boolean isUserInputValid() { + return fieldPollingTime.isValid() && fieldPollingOverdueTime.isValid(); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java index dc44e6de8..94e7d9fb7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java @@ -8,6 +8,11 @@ */ package org.eclipse.hawkbit.ui.tenantconfiguration; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; + import org.eclipse.hawkbit.ui.HawkbitUI; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; @@ -51,6 +56,9 @@ public class TenantConfigurationDashboardView extends CustomComponent @Autowired private AuthenticationConfigurationView authenticationConfigurationView; + @Autowired + private PollingConfigurationView pollingConfigurationView; + @Autowired private I18N i18n; @@ -60,6 +68,18 @@ public class TenantConfigurationDashboardView extends CustomComponent private Button saveConfigurationBtn; private Button undoConfigurationBtn; + private List configurationViews = new ArrayList(); + + /** + * init method adds all Configuration Views to the list of Views. + */ + @PostConstruct + public void init() { + configurationViews.add(defaultDistributionSetTypeLayout); + configurationViews.add(authenticationConfigurationView); + configurationViews.add(pollingConfigurationView); + } + @Override public void enter(final ViewChangeEvent event) { @@ -70,17 +90,20 @@ public class TenantConfigurationDashboardView extends CustomComponent rootLayout.setSizeFull(); rootLayout.setMargin(true); rootLayout.setSpacing(true); - rootLayout.addComponent(defaultDistributionSetTypeLayout); - rootLayout.addComponent(authenticationConfigurationView); + + configurationViews.forEach(view -> { + rootLayout.addComponent(view); + }); + final HorizontalLayout buttonContent = saveConfigurationButtonsLayout(); rootLayout.addComponent(buttonContent); rootLayout.setComponentAlignment(buttonContent, Alignment.BOTTOM_LEFT); rootPanel.setContent(rootLayout); setCompositionRoot(rootPanel); - authenticationConfigurationView.addChangeListener(this); - defaultDistributionSetTypeLayout.addChangeListener(this); - + configurationViews.forEach(view -> { + view.addChangeListener(this); + }); } private HorizontalLayout saveConfigurationButtonsLayout() { @@ -108,19 +131,30 @@ public class TenantConfigurationDashboardView extends CustomComponent } private void saveConfiguration() { - defaultDistributionSetTypeLayout.save(); - authenticationConfigurationView.save(); - // More methods - saveConfigurationBtn.setEnabled(false); - undoConfigurationBtn.setEnabled(false); - uINotification.displaySuccess(i18n.get("notification.configuration.save")); + boolean isUserInputValid = configurationViews.stream().allMatch(confView -> { + return confView.isUserInputValid(); + }); + + if (isUserInputValid) { + configurationViews.forEach(confView -> { + confView.save(); + }); + + // More methods + saveConfigurationBtn.setEnabled(false); + undoConfigurationBtn.setEnabled(false); + uINotification.displaySuccess(i18n.get("notification.configuration.save.successful")); + + } else { + uINotification.displayValidationError(i18n.get("notification.configuration.save.notpossible")); + } } private void undoConfiguration() { - defaultDistributionSetTypeLayout.undo(); - authenticationConfigurationView.undo(); - + configurationViews.forEach(confView -> { + confView.undo(); + }); // More methods saveConfigurationBtn.setEnabled(false); undoConfigurationBtn.setEnabled(false); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java new file mode 100644 index 000000000..7417ddc1b --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java @@ -0,0 +1,96 @@ +package org.eclipse.hawkbit.ui.tenantconfiguration.polling; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +import com.vaadin.data.Property; +import com.vaadin.data.util.converter.Converter.ConversionException; +import com.vaadin.shared.ui.datefield.Resolution; +import com.vaadin.ui.DateField; + +/** + * This class represents a Field which is optimized to enter a time duration in + * form HH:mm:ss (see {@link #DEFAULT_DURATION_FORMAT}). It uses the vaadin + * DateField as a basic element, but the format is optimized for the duration + * input. For a correct view of the popup it is recommended not to display the + * css-class "v-datefield-calendarpanel-header" and + * "v-datefield-calendarpanel-body" (see systemconfig.scss} + */ +public class DurationField extends DateField { + + private static final long serialVersionUID = 1L; + + private static String CSS_STYLE_NAME = "durationfield"; + + private static String DEFAULT_DURATION_FORMAT = "HH:mm:ss"; + private static String ADDITIONAL_DURATION_FORMAT = "HHmmss"; + + private SimpleDateFormat default_format = new SimpleDateFormat(DEFAULT_DURATION_FORMAT); + private SimpleDateFormat additional_format = new SimpleDateFormat(ADDITIONAL_DURATION_FORMAT); + + /** + * Creates a DurationField + */ + public DurationField() { + + default_format.setLenient(false); + additional_format.setLenient(false); + + this.setResolution(Resolution.SECOND); + this.setDateFormat(DEFAULT_DURATION_FORMAT); + this.addStyleName(CSS_STYLE_NAME); + + // needed that popup shows a 24h clock + this.setLocale(Locale.GERMANY); + // adds empty change Listener, but is needed that field reacts on + // pressed enter + this.addValueChangeListener(this); + } + + @Override + protected Date handleUnparsableDateString(String value) throws ConversionException { + + try { + return default_format.parse(value); + + } catch (ParseException e1) { + try { + return additional_format.parse(value); + } catch (ParseException e2) { + // if Parsing is not possible ConversionException is thrown + } + } + throw new ConversionException("input is not in HH:MM:SS format."); + } + + /** + * Sets the duration value as a String + * + * @param duration + * duration as String in format HH:mm:ss, only values <= 23:59:59 + * are excepted + * @throws ParseException + * Exception is thrown, when String parameter is in wrong + * format. + */ + public void setValueAsString(String duration) throws ParseException { + super.setValue(default_format.parse(duration)); + } + + /** + * Gets the duration value as a formated String + * + * @return duration as String in format HH:mm:ss + */ + public String getValueAsString() { + return default_format.format(super.getValue()); + } + + @Override + public void valueChange(Property.ValueChangeEvent event) { + // does nothing, but method overrides super methods and is needed that + // parsing works correctly on pressed enter key + } +} diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index c63b0ba8a..209569ff0 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -390,12 +390,16 @@ link.support.name=Support link.usermanagement.name=User Management # System Configuration View -notification.configuration.save=Saved changes +notification.configuration.save.successful=Saved changes +notification.configuration.save.notpossible = Saving was not possible, because of invalid user input. configuration.defaultdistributionset.title=Distribution Set Type configuration.defaultdistributionset.select.label=Select the default Distribution Set type: configuration.savebutton.tooltip=Save Configurations configuration.cancellbutton.tooltip=Cancel Configurations configuration.authentication.title=Authentication Configuration +configuration.polling.title=Polling Configuration +configuration.polling.time=Polling Time +configuration.polling.overduetime=Polling Overdue Time #Calendar calendar.year=year diff --git a/hawkbit-ui/src/main/resources/messages_en.properties b/hawkbit-ui/src/main/resources/messages_en.properties index 762b68c56..74f50f378 100644 --- a/hawkbit-ui/src/main/resources/messages_en.properties +++ b/hawkbit-ui/src/main/resources/messages_en.properties @@ -380,6 +380,9 @@ configuration.defaultdistributionset.select.label=Select the default Distributio configuration.savebutton.tooltip=Save Configurations configuration.cancellbutton.tooltip=Cancel Configurations configuration.authentication.title=Authentication Configuration +controller.polling.title=Polling Configuration +controller.polling.time=Polling Time +controller.polling.overduetime=Polling Overdue Time #Calendar calendar.year=year From acc0770d36e815589efbade2d5b83d9bfec4bd2f Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 22 Dec 2015 16:34:24 +0100 Subject: [PATCH 02/42] Changed stylesheet to disable calender in popup of DurationField. * calender popup should only show the time selector, because the modified DurationField only uses this value Signed-off-by: Nonnenmacher Fabian --- .../VAADIN/themes/hawkbit/customstyles/systemconfig.scss | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/systemconfig.scss b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/systemconfig.scss index 95eea57f2..ee88a1398 100644 --- a/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/systemconfig.scss +++ b/hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/systemconfig.scss @@ -44,5 +44,11 @@ bottom: 13px; color: $button-icon-color; } + } -} + + .durationfield .v-datefield-calendarpanel-header, + .durationfield .v-datefield-calendarpanel-body { + display: none; + } +} \ No newline at end of file From 1f9c6bfd722d3b961bea00df6eb05a112714b41c Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 7 Jan 2016 12:46:53 +0100 Subject: [PATCH 03/42] Changed datamodel, integrated poll configuration into tenant meta data table * updated sql scripts to update new collums * updated coressponding JPA class TenantMetaData Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/ControllerPollProperties.java | 3 --- .../repository/model/TenantMetaData.java | 21 +++++++++++++++++++ ...0__update_target_meta_for_polling___H2.sql | 2 ++ ...pdate_target_meta_for_polling___MYSQL2.sql | 3 +++ 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql create mode 100644 hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java index 694d5c016..7c33301f3 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java @@ -13,8 +13,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; /** * Defines the polling time for the controllers in HH:MM:SS notation. * - * - * */ @ConfigurationProperties(prefix = "hawkbit.controller") @@ -38,5 +36,4 @@ public class ControllerPollProperties { public void setPollingOverdueTime(final String pollingOverdue) { this.pollingOverdueTime = pollingOverdue; } - } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java index e86bfe8a4..4e47f856d 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java @@ -60,6 +60,12 @@ public class TenantMetaData implements Serializable { @Column(name = "tenant", nullable = false, length = 40) private String tenant; + @Column(name = "polling_time", nullable = true, length = 10) + private String pollingTime; + + @Column(name = "polling_overdue_time", nullable = true, length = 10) + private String pollingOverdueTime; + private String createdBy; private String lastModifiedBy; private Long createdAt; @@ -256,4 +262,19 @@ public class TenantMetaData implements Serializable { return true; } + public String getPollingTime() { + return pollingTime; + } + + public void setPollingTime(String pollingTime) { + this.pollingTime = pollingTime; + } + + public String getPollingOverdueTime() { + return pollingOverdueTime; + } + + public void setPollingOverdueTime(String pollingOverdueTime) { + this.pollingOverdueTime = pollingOverdueTime; + } } diff --git a/hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql b/hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql new file mode 100644 index 000000000..17ec505bf --- /dev/null +++ b/hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql @@ -0,0 +1,2 @@ +ALTER TABLE sp_tenant ADD polling_time varchar(10); +ALTER TABLE sp_tenant ADD polling_overdue_time varchar(10); diff --git a/hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql b/hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql new file mode 100644 index 000000000..3f0aadde6 --- /dev/null +++ b/hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql @@ -0,0 +1,3 @@ +ALTER TABLE sp_tenant ADD polling_time varchar(10); +ALTER TABLE sp_tenant ADD polling_overdue_time varchar(10); + From 07e0fb30325504c8ce158ba60698df8e04591293 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 7 Jan 2016 12:48:20 +0100 Subject: [PATCH 04/42] First Implemantation of Configuration Logic Signed-off-by: Nonnenmacher Fabian --- .../model/helper/PollConfigurationHelper.java | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java index 7f5978a2d..48a55f9b0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java @@ -13,6 +13,7 @@ import java.time.Duration; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ControllerPollProperties; +import org.eclipse.hawkbit.repository.SystemManagement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,6 +33,11 @@ import org.springframework.context.EnvironmentAware; */ public final class PollConfigurationHelper { + /** + * Expected format of the Polling Time String + */ + public static final String EXPECTED_POLLING_TIME_FORMAT = "(([0-1]?[0-9]|2[0-3])(:[0-5][0-9]){2})"; + private static final Logger LOG = LoggerFactory.getLogger(PollConfigurationHelper.class); private static final PollConfigurationHelper INSTANCE = new PollConfigurationHelper(); @@ -46,6 +52,9 @@ public final class PollConfigurationHelper { @Autowired private ControllerPollProperties controllerPollProperties; + @Autowired + private SystemManagement systemManagement; + private Duration controllerPollTimeDuration; private Duration controllerOverduePollTimeDuration; @@ -53,7 +62,7 @@ public final class PollConfigurationHelper { } /** - * Bean post construct to calcualte the poll time and poll overdue time only + * Bean post construct to calculate the poll time and poll overdue time only * once. */ @PostConstruct @@ -67,7 +76,6 @@ public final class PollConfigurationHelper { DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, DEFAULT_OVERDUE_SECOND); this.controllerOverduePollTimeDuration = Duration.ZERO.plusHours(controllerOverduePollTimeSplit[0]) .plusMinutes(controllerOverduePollTimeSplit[1]).plusSeconds(controllerOverduePollTimeSplit[2]); - } /** @@ -79,6 +87,15 @@ public final class PollConfigurationHelper { return controllerPollTimeDuration; } + /** + * @return the poll time interval configured in the configuration + * {@code hawkbit.server.controller.polling} or the default value + * which is {@code 00:05:00} never {@code null}. + */ + public String getPollTimeIntervalAsFormattedString() { + return durationToFormattedString(controllerPollTimeDuration); + } + /** * @return the overdue poll threshold configured in the configuration * {@code hawkbit.server.controller.polling.overdue} or the default @@ -88,6 +105,16 @@ public final class PollConfigurationHelper { return controllerOverduePollTimeDuration; } + /** + * @return the overdue poll threshold as a formatted string (HH:MM:SS) + * configured in the configuration + * {@code hawkbit.server.controller.polling.overdue} or the default + * value which is {@code 00:05:00} never {@code null}. + */ + public String getOverduePollTimeIntervalAsFormattedString() { + return durationToFormattedString(controllerOverduePollTimeDuration); + } + /** * @return a singleton instance of the environment helper. */ @@ -110,4 +137,38 @@ public final class PollConfigurationHelper { LOG.warn("Using default configuration hour:{} min:{}, second:{}", defaultHour, defaultMinute, defaultSecond); return new long[] { defaultHour, defaultMinute, defaultSecond }; } + + private String durationToFormattedString(Duration duration) { + long seconds = duration.getSeconds(); + long minuts = seconds / 60; + long hours = minuts / 60; + + seconds = seconds % 60; + minuts = minuts % 60; + hours = hours % 100; + + return String.format("%02d:%02d:%02d", hours, minuts, seconds); + } + + private Duration formattedStringToDuration(String formattedDuration) { + if (formattedDuration == null || !formattedDuration.matches(EXPECTED_POLLING_TIME_FORMAT)) { + LOG.warn("Cannot parse the given poll configuration {}", formattedDuration); + throw new IllegalArgumentException( + "String is not in the EXPECTED_POLLING_TIME_FORMAT. Parsing not possible."); + } + + final String[] split = formattedDuration.split(":"); + if (split.length == 3) { + try { + return Duration.ofHours(Long.parseLong(split[0])).plusMinutes(Long.parseLong(split[1])) + .plusSeconds(Long.parseLong(split[2])); + } catch (final NumberFormatException e) { + LOG.warn("Cannot parse the given poll configuration {}", formattedDuration); + } + } + + LOG.error("Cannot parse the given poll String {}, even it matches the regex \"{}\".", formattedDuration, + EXPECTED_POLLING_TIME_FORMAT); + throw new IllegalArgumentException("String is in the expected format. But parsing is not possible anyway."); + } } From 1eedd3a531f2f541a51574c5725996cfd93cd1d0 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 14 Jan 2016 13:08:50 +0100 Subject: [PATCH 05/42] Implemented Buisnesslogic to read and save correct polling configuration - added min and max values to config files - updated ControllerPollProperties: added getter and setter of min and max values - updated PollConfigurationHelper: added getter for different values Signed-off-by: Nonnenmacher Fabian --- .../main/resources/hawkbitdefaults.properties | 4 + .../hawkbit/ControllerPollProperties.java | 18 + .../model/helper/PollConfigurationHelper.java | 368 +++++++++++++----- 3 files changed, 288 insertions(+), 102 deletions(-) diff --git a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties index 98749a384..d3ddb6483 100644 --- a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties +++ b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties @@ -48,6 +48,10 @@ hawkbit.threadpool.queuesize=20000 # Defines the polling time for the controllers in HH:MM:SS notation hawkbit.controller.pollingTime=00:05:00 hawkbit.controller.pollingOverdueTime=00:05:00 +hawkbit.controller.maxPollingTime=23:59:59 +hawkbit.controller.minPollingTime=00:00:30 +# Attention: if you want to use a maximumPollingTime greater 23:59:59 you have to update the DurationField in the configuration window + ## Configuration for RabbitMQ integration hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java index 7c33301f3..1c19b35d0 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java @@ -20,6 +20,8 @@ public class ControllerPollProperties { private String pollingTime = "00:05:00"; private String pollingOverdueTime = "00:05:00"; + private String maxPollingTime = "23:59:00"; + private String minPollingTime = "23:59:00"; public String getPollingTime() { return pollingTime; @@ -36,4 +38,20 @@ public class ControllerPollProperties { public void setPollingOverdueTime(final String pollingOverdue) { this.pollingOverdueTime = pollingOverdue; } + + public String getMaxPollingTime() { + return maxPollingTime; + } + + public void setMaxPollingTime(String maxPollingTime) { + this.maxPollingTime = maxPollingTime; + } + + public String getMinPollingTime() { + return minPollingTime; + } + + public void setMinPollingTime(String minPollingTime) { + this.minPollingTime = minPollingTime; + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java index 48a55f9b0..9b9d24de9 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java @@ -9,8 +9,13 @@ package org.eclipse.hawkbit.repository.model.helper; import java.time.Duration; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAccessor; import javax.annotation.PostConstruct; +import javax.validation.constraints.NotNull; import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.repository.SystemManagement; @@ -26,17 +31,14 @@ import org.springframework.context.EnvironmentAware; * configuration in beans not instatinated by spring e.g. JPA entities which * cannot implement the {@link EnvironmentAware} interface to retrieve * environment variables. - * - * - * - * */ public final class PollConfigurationHelper { /** - * Expected format of the Polling Time String + * Format of the expected Duration String. Pattern has to be in Valid Format + * for SimpleDateFormat */ - public static final String EXPECTED_POLLING_TIME_FORMAT = "(([0-1]?[0-9]|2[0-3])(:[0-5][0-9]){2})"; + public static final String DURATION_FORMAT = "HH:mm:ss"; private static final Logger LOG = LoggerFactory.getLogger(PollConfigurationHelper.class); private static final PollConfigurationHelper INSTANCE = new PollConfigurationHelper(); @@ -49,71 +51,24 @@ public final class PollConfigurationHelper { private static final int DEFAULT_POLL_MINUTE = 5; private static final int DEFAULT_POLL_SECOND = 0; + private static final int DEFAULT_MAX_HOUR = 23; + private static final int DEFAULT_MAX_MINUTE = 59; + private static final int DEFAULT_MAX_SECOND = 59; + + private static final int DEFAULT_MIN_HOUR = 0; + private static final int DEFAULT_MIN_MINUTE = 0; + private static final int DEFAULT_MIN_SECOND = 30; + @Autowired private ControllerPollProperties controllerPollProperties; @Autowired private SystemManagement systemManagement; - private Duration controllerPollTimeDuration; - private Duration controllerOverduePollTimeDuration; - - private PollConfigurationHelper() { - } - - /** - * Bean post construct to calculate the poll time and poll overdue time only - * once. - */ - @PostConstruct - public void postConstruct() { - final long[] controllerPollTimeSplit = splitInterval(controllerPollProperties.getPollingTime(), - DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, DEFAULT_POLL_SECOND); - this.controllerPollTimeDuration = Duration.ZERO.plusHours(controllerPollTimeSplit[0]) - .plusMinutes(controllerPollTimeSplit[1]).plusSeconds(controllerPollTimeSplit[2]); - - final long[] controllerOverduePollTimeSplit = splitInterval(controllerPollProperties.getPollingOverdueTime(), - DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, DEFAULT_OVERDUE_SECOND); - this.controllerOverduePollTimeDuration = Duration.ZERO.plusHours(controllerOverduePollTimeSplit[0]) - .plusMinutes(controllerOverduePollTimeSplit[1]).plusSeconds(controllerOverduePollTimeSplit[2]); - } - - /** - * @return the poll time interval configured in the configuration - * {@code hawkbit.server.controller.polling} or the default value - * which is {@code 00:05:00} never {@code null}. - */ - public Duration getPollTimeInterval() { - return controllerPollTimeDuration; - } - - /** - * @return the poll time interval configured in the configuration - * {@code hawkbit.server.controller.polling} or the default value - * which is {@code 00:05:00} never {@code null}. - */ - public String getPollTimeIntervalAsFormattedString() { - return durationToFormattedString(controllerPollTimeDuration); - } - - /** - * @return the overdue poll threshold configured in the configuration - * {@code hawkbit.server.controller.polling.overdue} or the default - * value which is {@code 00:05:00} never {@code null}. - */ - public Duration getOverduePollTimeInterval() { - return controllerOverduePollTimeDuration; - } - - /** - * @return the overdue poll threshold as a formatted string (HH:MM:SS) - * configured in the configuration - * {@code hawkbit.server.controller.polling.overdue} or the default - * value which is {@code 00:05:00} never {@code null}. - */ - public String getOverduePollTimeIntervalAsFormattedString() { - return durationToFormattedString(controllerOverduePollTimeDuration); - } + private Duration configurationPollTime; + private Duration configurationOverduePollTime; + private Duration configurationMaximumPollTime; + private Duration configurationMinimumPollTime; /** * @return a singleton instance of the environment helper. @@ -122,53 +77,262 @@ public final class PollConfigurationHelper { return INSTANCE; } - private long[] splitInterval(final String interval, final long defaultHour, final long defaultMinute, - final long defaultSecond) { - if (interval != null) { - final String[] split = interval.split(":"); - if (split.length == 3) { - try { - return new long[] { Long.parseLong(split[0]), Long.parseLong(split[1]), Long.parseLong(split[2]) }; - } catch (final NumberFormatException e) { - LOG.warn("Cannot parse the given poll configuration {}", interval); - } - } - } - LOG.warn("Using default configuration hour:{} min:{}, second:{}", defaultHour, defaultMinute, defaultSecond); - return new long[] { defaultHour, defaultMinute, defaultSecond }; + /** + * Bean post construct to calculate the poll time and poll overdue time only + * once. + */ + @PostConstruct + public void initializeConfigurationValues() { + + readGlobalDurationsFromConfiguration(); + + validateGlobalDurations(); } - private String durationToFormattedString(Duration duration) { - long seconds = duration.getSeconds(); - long minuts = seconds / 60; - long hours = minuts / 60; + private void readGlobalDurationsFromConfiguration() { + try { + configurationMaximumPollTime = formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); + } catch (DateTimeParseException e) { + // Set to default values + configurationMaximumPollTime = getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, + DEFAULT_MAX_SECOND); + } - seconds = seconds % 60; - minuts = minuts % 60; - hours = hours % 100; + try { + configurationMinimumPollTime = formattedStringToDuration(controllerPollProperties.getMinPollingTime()); + } catch (DateTimeParseException e) { + // Set to default values + configurationMinimumPollTime = getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, + DEFAULT_MIN_SECOND); + } + + try { + configurationPollTime = formattedStringToDuration(controllerPollProperties.getPollingTime()); + } catch (DateTimeParseException e) { + configurationPollTime = getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, + DEFAULT_POLL_SECOND); + } + + try { + configurationOverduePollTime = formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); + } catch (DateTimeParseException e) { + configurationOverduePollTime = getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, + DEFAULT_OVERDUE_SECOND); + } - return String.format("%02d:%02d:%02d", hours, minuts, seconds); } - private Duration formattedStringToDuration(String formattedDuration) { - if (formattedDuration == null || !formattedDuration.matches(EXPECTED_POLLING_TIME_FORMAT)) { - LOG.warn("Cannot parse the given poll configuration {}", formattedDuration); - throw new IllegalArgumentException( - "String is not in the EXPECTED_POLLING_TIME_FORMAT. Parsing not possible."); + private void validateGlobalDurations() { + + if (configurationMaximumPollTime.compareTo(configurationMinimumPollTime) < 0) { + // min value > max value -> use default values for both durations + LOG.warn("The configured maximum value of the polling time is smaller" + + " than the configured minimum value. Both are replaced by default values."); + + configurationMaximumPollTime = getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, + DEFAULT_MAX_SECOND); + configurationMinimumPollTime = getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, + DEFAULT_MIN_SECOND); } - final String[] split = formattedDuration.split(":"); - if (split.length == 3) { - try { - return Duration.ofHours(Long.parseLong(split[0])).plusMinutes(Long.parseLong(split[1])) - .plusSeconds(Long.parseLong(split[2])); - } catch (final NumberFormatException e) { - LOG.warn("Cannot parse the given poll configuration {}", formattedDuration); + if (!isWithinRange(configurationPollTime)) { + // poll time value not within allowed range ==> use default value + configurationPollTime = getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, + DEFAULT_POLL_SECOND); + } + + if (!isWithinRange(configurationOverduePollTime)) { + // overdue poll time value not within range => use default value + configurationOverduePollTime = getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, + DEFAULT_OVERDUE_SECOND); + } + } + + private boolean isWithinRange(@NotNull Duration duration) { + + return duration.compareTo(configurationMinimumPollTime) > 0 + && duration.compareTo(configurationMaximumPollTime) < 0; + } + + /** + * @return the poll time interval stored in the tenant meta data. If there + * is no tenant specific configuration the global value, configured + * in the configuration {@code hawkbit.server.controller.polling} or + * the default value which is {@code 00:05:00} never {@code null}. + */ + public Duration getPollTimeInterval() { + Duration tenantPollTimeInterval = getTenantPollTimeIntervall(); + + if (tenantPollTimeInterval != null) { + return tenantPollTimeInterval; + } + return configurationPollTime; + } + + /** + * @return the poll time interval stored in the tenant meta data. If there + * is no value stored this function returns {@code null} + */ + public Duration getTenantPollTimeIntervall() { + String tenantPollingTime = systemManagement.getTenantMetadata().getPollingTime(); + + return validateDurationStringAndGetDuration(tenantPollingTime, "polling time"); + } + + /** + * @return the poll time interval configured in the configuration + * {@code hawkbit.server.controller.polling} or the default value + * which is {@code 00:05:00} never {@code null}. This method ignores + * eventual tenant specific configurations. + */ + public Duration getGlobalPollTimeInterval() { + return configurationPollTime; + } + + /** + * Stores the changed value in the tenant meta data configuration. The value + * {@code null} is clearly allowed. Setting the poll time to {@code null} + * means no specific tenant configuration and global configuration are used. + * + * @param pollingTime + * polling time interval as formatted string {@code HH:mm:ss} or + * {@code null} + */ + public void setTenantPollTimeIntervall(Duration pollingTime) { + if (pollingTime == null) { + systemManagement.getTenantMetadata().setPollingTime(null); + return; + } + systemManagement.getTenantMetadata().setPollingTime(durationToFormattedString(pollingTime)); + } + + /** + * @return the overdue poll time interval stored in the tenant meta data. If + * there is no tenant specific configuration the global value, + * configured in the configuration + * {@code hawkbit.server.controller.polling} or the default value + * which is {@code 00:05:00} never {@code null}. + */ + public Duration getOverduePollTimeInterval() { + Duration tenantOverduePollTimeInterval = getTenantOverduePollTimeIntervall(); + + if (tenantOverduePollTimeInterval != null) { + return tenantOverduePollTimeInterval; + } + return configurationOverduePollTime; + }; + + /** + * @return the poll time interval stored in the tenant meta data. If there + * is no value stored this function returns {@code null} + */ + public Duration getTenantOverduePollTimeIntervall() { + String tenantOverduePollingTime = systemManagement.getTenantMetadata().getPollingOverdueTime(); + + return validateDurationStringAndGetDuration(tenantOverduePollingTime, "overdue polling time"); + } + + private Duration validateDurationStringAndGetDuration(String pollingTime, String paramNameForLog) { + if (pollingTime == null) { + return null; + } + + try { + Duration d = formattedStringToDuration(pollingTime); + + if (isWithinRange(d)) { + return d; } + + LOG.warn("Tenant {} has stored a {} {} which is not in the allowed range.", + systemManagement.currentTenant(), paramNameForLog, pollingTime); + + } catch (DateTimeParseException ex) { + LOG.warn("Tenant {} has stored an invalid {} {} in its meta data.", systemManagement.currentTenant(), + paramNameForLog, pollingTime); + } + return null; + } + + /** + * @return the overdue poll time interval configured in the configuration + * {@code hawkbit.server.controller.polling.overdue} or the default + * value which is {@code 00:05:00} never {@code null}. + */ + public Duration getGlobalOverduePollTimeInterval() { + return configurationOverduePollTime; + } + + /** + * Stores the polling overtime interval value in the tenant meta data + * configuration. The value {@code null} is clearly allowed. Setting the + * overdue poll time to {@code null} means no specific tenant configuration + * and global configuration are used. + * + * @param pollingTime + * polling time interval as formatted string {@code HH:mm:ss} or + * {@code null} + */ + public void setTenantOverduePollTimeIntervall(Duration pollingTime) { + if (pollingTime == null) { + systemManagement.getTenantMetadata().setPollingOverdueTime(null); + return; } - LOG.error("Cannot parse the given poll String {}, even it matches the regex \"{}\".", formattedDuration, - EXPECTED_POLLING_TIME_FORMAT); - throw new IllegalArgumentException("String is in the expected format. But parsing is not possible anyway."); + systemManagement.getTenantMetadata().setPollingOverdueTime(durationToFormattedString(pollingTime)); + } + + /** + * @return the maximum poll time duration configured in the configuration + * {@code hawkbit.server.controller.polling.overdue} or the default + * value which is {@code 23:59:00} never {@code null}. + */ + public Duration getMaximumPollingInterval() { + return configurationMaximumPollTime; + } + + /** + * @return the minimum poll time duration configured in the configuration + * {@code hawkbit.server.controller.polling.overdue} or the default + * value which is {@code 23:59:00} never {@code null}. + */ + public Duration getMinimumPollingInterval() { + return configurationMinimumPollTime; + } + + private String durationToFormattedString(@NotNull Duration duration) { + return LocalTime.ofNanoOfDay(duration.toNanos()).format(DateTimeFormatter.ofPattern(DURATION_FORMAT)); + } + + private Duration formattedStringToDuration(String formattedDuration) throws DateTimeParseException { + final TemporalAccessor ta = DateTimeFormatter.ofPattern(DURATION_FORMAT).parse(formattedDuration.trim()); + return Duration.between(LocalTime.MIDNIGHT, LocalTime.from(ta)); + } + + private Duration getDurationByTimeValues(long hours, long minutes, long seconds) { + return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); + } + + /** + * sets the ControllerPollProperties in a not spring handled context. Don't + * forget to call {@code initializeConfigurationValues} afterwards to read + * the values from the PollProperties. + * + * @param controllerPollProperties + * the controll properties + */ + public void setControllerPollProperties(ControllerPollProperties controllerPollProperties) { + this.controllerPollProperties = controllerPollProperties; + } + + /** + * sets the SystemManagement instance which is responsible for tenant + * specific configuration. + * + * @param systemManagement + * the SystemManagemnt instance + */ + public void setSystemManagement(SystemManagement systemManagement) { + this.systemManagement = systemManagement; } } From cb3e6863c10350882d08921bee272921fde62ded Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 7 Jan 2016 12:56:40 +0100 Subject: [PATCH 06/42] Updated UI to handle all requirements * added DurationConfigField (Field which contains a DurationConfigField and a Checkbox) * added labels to messages.properties * added new Interface ConfigurationElement, with functionallity which is important for saving the data Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/repository/model/TargetInfo.java | 7 +- .../ConfigurationElement.java | 35 +++ .../ConfigurationGroup.java | 34 +-- .../PollingConfigurationView.java | 122 +++++------ .../TenantConfigurationDashboardView.java | 2 +- .../polling/DurationConfigField.java | 181 ++++++++++++++++ .../polling/DurationField.java | 199 ++++++++++++++---- .../src/main/resources/messages.properties | 1 + 8 files changed, 440 insertions(+), 141 deletions(-) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationElement.java create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index d491319fa..f00b4880e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -110,7 +110,7 @@ public class TargetInfo implements Persistable, Serializable { @CollectionTable(name = "sp_target_attributes", joinColumns = { @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target") ) // use deprecated annotation until HHH-8862 is fixed - @SuppressWarnings("deprecation") + // @org.hibernate.annotations.ForeignKey( name = "fk_targ_attrib_target" ) private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); @@ -181,7 +181,7 @@ public class TargetInfo implements Persistable, Serializable { } /** - * @param ipAddress + * @param address * the ipAddress to set * * @throws IllegalArgumentException @@ -382,6 +382,9 @@ public class TargetInfo implements Persistable, Serializable { return overdueDate; } + /** + * @return the current date + */ public LocalDateTime getCurrentDate() { return currentDate; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationElement.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationElement.java new file mode 100644 index 000000000..7614f852f --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationElement.java @@ -0,0 +1,35 @@ +package org.eclipse.hawkbit.ui.tenantconfiguration; + +import java.io.Serializable; + +public interface ConfigurationElement { + + /** + * called to verify that the Input done by the user is valid + * + * @return true when the data is valid, false otherwise + */ + boolean isUserInputValid(); + + /** + * Adds a configuration change listener to notify about configuration + * changes. + * + * @param listener + * the listener to be notified in case the item changes some + * configuration + */ + void addChangeListener(ConfigurationGroupChangeListener listener); + + /** + * Configuration Change Listener to be notified about configuration changes + * in configuration group. + * + */ + interface ConfigurationGroupChangeListener extends Serializable { + /** + * called to notify about configuration has been changed. + */ + void configurationChanged(); + } +} \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java index 60f1934f9..1d2245394 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.ui.tenantconfiguration; -import java.io.Serializable; - import com.vaadin.ui.Component; /** @@ -17,7 +15,7 @@ import com.vaadin.ui.Component; * * */ -public interface ConfigurationGroup extends Component { +public interface ConfigurationGroup extends Component, ConfigurationElement { /** * called to store any configuration changes. @@ -28,34 +26,4 @@ public interface ConfigurationGroup extends Component { * called to rollback any configuration changes. */ void undo(); - - /** - * called to verify that the Input done by the user is valid - * - * @return true when the data is valid, false otherwise - */ - boolean isUserInputValid(); - - /** - * Adds a configuration change listener to notify about configuration - * changes. - * - * @param listener - * the listener to be notified in case the item changes some - * configuration - */ - void addChangeListener(ConfigurationGroupChangeListener listener); - - /** - * Configuration Change Listener to be notified about configuration changes - * in configuration group. - * - */ - interface ConfigurationGroupChangeListener extends Serializable { - /** - * called to notify about configuration has been changed. - */ - void configurationChanged(); - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 3a5fb92a0..b57c960a2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -1,23 +1,18 @@ package org.eclipse.hawkbit.ui.tenantconfiguration; -import static org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper.EXPECTED_POLLING_TIME_FORMAT; +import java.time.Duration; import javax.annotation.PostConstruct; -import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; -import org.eclipse.hawkbit.ui.tenantconfiguration.polling.DurationField; +import org.eclipse.hawkbit.ui.tenantconfiguration.polling.DurationConfigField; import org.eclipse.hawkbit.ui.utils.I18N; import org.springframework.beans.factory.annotation.Autowired; -import com.vaadin.data.Property.ValueChangeEvent; -import com.vaadin.data.Validator; import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; -import com.vaadin.ui.Field; import com.vaadin.ui.Label; import com.vaadin.ui.Panel; -import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; /** @@ -29,21 +24,24 @@ import com.vaadin.ui.VerticalLayout; @SpringComponent @ViewScope public class PollingConfigurationView extends BaseConfigurationView - implements ConfigurationGroup, Field.ValueChangeListener { + implements ConfigurationGroup, ConfigurationElement.ConfigurationGroupChangeListener { private static final long serialVersionUID = 1L; - @Autowired - private transient SystemManagement systemManagement; - @Autowired private I18N i18n; @Autowired PollConfigurationHelper pollConfigurationHelper; - final private DurationField fieldPollingTime = new DurationField(); - final private DurationField fieldPollingOverdueTime = new DurationField(); + @Autowired + private DurationConfigField fieldPollingTime; + + @Autowired + private DurationConfigField fieldPollingOverdueTime; + + private Duration tenantPollingTime; + private Duration tenantPollingOverdueTime; /** * Initialize Authentication Configuration layout. @@ -51,38 +49,34 @@ public class PollingConfigurationView extends BaseConfigurationView @PostConstruct public void init() { - Validator correctFormatValidator = new Validator() { - private static final long serialVersionUID = 1L; - - @Override - public void validate(Object value) throws InvalidValueException { - if (!(value instanceof String) || !((String) value).matches(EXPECTED_POLLING_TIME_FORMAT)) { - throw new InvalidValueException("Not in HH:MM:SS Format."); - } - } - }; - final Panel rootPanel = new Panel(); rootPanel.setSizeFull(); - rootPanel.addStyleName("config-panel"); - // TODO Better Layout than Vertical Layout - maybe a table layout? final VerticalLayout vLayout = new VerticalLayout(); vLayout.setMargin(true); - vLayout.setSizeFull(); + // vLayout.setSizeFull(); final Label headerDisSetType = new Label(i18n.get("configuration.polling.title")); headerDisSetType.addStyleName("config-panel-header"); vLayout.addComponent(headerDisSetType); - final Label labelPollingTime = new Label(i18n.get("configuration.polling.time")); - vLayout.addComponent(labelPollingTime); + tenantPollingTime = pollConfigurationHelper.getTenantPollTimeIntervall(); + fieldPollingTime.setInitValues(i18n.get("configuration.polling.time"), tenantPollingTime, + pollConfigurationHelper.getGlobalPollTimeInterval()); + fieldPollingTime.setAllowedRange(pollConfigurationHelper.getMinimumPollingInterval(), + pollConfigurationHelper.getMaximumPollingInterval()); + fieldPollingTime.addChangeListener(this); vLayout.addComponent(fieldPollingTime); - final Label labelPollingOverdueTime = new Label(i18n.get("configuration.polling.overduetime")); - vLayout.addComponent(labelPollingOverdueTime); + tenantPollingOverdueTime = pollConfigurationHelper.getTenantOverduePollTimeIntervall(); + + fieldPollingOverdueTime.setInitValues(i18n.get("configuration.polling.overduetime"), tenantPollingOverdueTime, + pollConfigurationHelper.getGlobalOverduePollTimeInterval()); + fieldPollingOverdueTime.setAllowedRange(pollConfigurationHelper.getMinimumPollingInterval(), + pollConfigurationHelper.getMaximumPollingInterval()); + fieldPollingOverdueTime.addChangeListener(this); vLayout.addComponent(fieldPollingOverdueTime); @@ -90,55 +84,47 @@ public class PollingConfigurationView extends BaseConfigurationView setCompositionRoot(rootPanel); } - /* - * (non-Javadoc) - * - * @see - * com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin.data. - * Property.ValueChangeEvent) - * - * This method is called when a value of a textField changes. When the value - * is not in the correct format, but has valid data, this method will change - * the value to the correct format - */ @Override - public void valueChange(ValueChangeEvent event) { + public void save() { + // make sure values are only saved, when the value has been changed - notifyConfigurationChanged(); + if (!compareDurations(tenantPollingTime, fieldPollingTime.getValue())) { + tenantPollingTime = fieldPollingTime.getValue(); + pollConfigurationHelper.setTenantPollTimeIntervall(fieldPollingTime.getValue()); + } - if (event.getProperty() instanceof TextField) { - TextField textfield = (TextField) event.getProperty(); - - String value = textfield.getValue(); - - if (value.matches("[0-9]{1,6}")) { - value = "000000".substring(value.length()) + value; - value = value.substring(0, 2) + ":" + value.substring(2, 4) + ":" + value.substring(4, 6); - } - - if (value.matches("([0-5]?[0-9]?(:[0-5][0-9]){1,2})")) { - value = "00:00:00".substring(0, 8 - value.length()) + value; - } - - if (value.matches(EXPECTED_POLLING_TIME_FORMAT)) { - textfield.setValue(value); - } + if (!compareDurations(tenantPollingOverdueTime, fieldPollingOverdueTime.getValue())) { + tenantPollingOverdueTime = fieldPollingOverdueTime.getValue(); + pollConfigurationHelper.setTenantOverduePollTimeIntervall(fieldPollingOverdueTime.getValue()); } } - @Override - public void save() { - // TODO Auto-generated method stub - } - @Override public void undo() { - + fieldPollingTime.setValue(tenantPollingTime); + fieldPollingOverdueTime.setValue(tenantPollingOverdueTime); } @Override public boolean isUserInputValid() { - return fieldPollingTime.isValid() && fieldPollingOverdueTime.isValid(); + return fieldPollingTime.isUserInputValid() && fieldPollingOverdueTime.isUserInputValid(); } + @Override + public void configurationChanged() { + notifyConfigurationChanged(); + } + + private boolean compareDurations(Duration d1, Duration d2) { + if (d1 == null && d2 == null) { + return true; + } + + if (d1 != null) { + return d1.equals(d2); + } + + // d1 == null, d2 != null + return false; + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java index 94e7d9fb7..b8873a5bb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java @@ -17,7 +17,7 @@ import org.eclipse.hawkbit.ui.HawkbitUI; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; -import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationGroup.ConfigurationGroupChangeListener; +import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationElement.ConfigurationGroupChangeListener; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java new file mode 100644 index 000000000..5555037a6 --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -0,0 +1,181 @@ +package org.eclipse.hawkbit.ui.tenantconfiguration.polling; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationElement; +import org.eclipse.hawkbit.ui.utils.I18N; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.spring.annotation.SpringComponent; +import com.vaadin.spring.annotation.ViewScope; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.GridLayout; +import com.vaadin.ui.Label; + +/** + * The DurationConfigField consists of three vaadin fields. A {@link #Label} + * {@link #DurationField} and a {@link #CheckBox}. The user can then enter a + * duration in the DurationField or he can configure using the global duration + * by changing the CheckBox. + */ +@SpringComponent +@ViewScope +@Scope("prototype") +public class DurationConfigField extends GridLayout implements ValueChangeListener, ConfigurationElement { + + private static final long serialVersionUID = 1L; + + private final List configurationChangeListeners = new ArrayList<>(); + + private CheckBox checkBox; + private DurationField durationField; + + private Duration globalDuration; + + @Autowired + private I18N i18n; + + /** + * sets i18n + * + * @param i18n + */ + public void setI18n(I18N i18n) { + this.i18n = i18n; + } + + public DurationConfigField() { + super(3, 2); + } + + /** + * Initialize Authentication Configuration layout. + */ + @PostConstruct + public void init() { + + this.addStyleName("duration-config-field"); + this.setSpacing(true); + this.setImmediate(true); + this.setColumnExpandRatio(1, 1.0F); + // gridLayout.setSizeFull(); + + checkBox = new CheckBox(); + + this.addComponent(checkBox, 0, 0); + this.setComponentAlignment(checkBox, Alignment.MIDDLE_LEFT); + + Label customValue = SPUIComponentProvider.getLabel(i18n.get("configuration.polling.custom.value"), + SPUILabelDefinitions.SP_LABEL_SIMPLE); + this.addComponent(customValue, 1, 0); + this.setComponentAlignment(customValue, Alignment.MIDDLE_LEFT); + + durationField = new DurationField(); + + this.addComponent(durationField, 2, 0); + this.setComponentAlignment(durationField, Alignment.MIDDLE_LEFT); + + checkBox.addValueChangeListener(this); + } + + @Override + public void valueChange(ValueChangeEvent event) { + if (event.getProperty() == checkBox) { + if (checkBox.getValue()) { + durationField.setEnabled(true); + } else { + durationField.setDuration(globalDuration); + durationField.setEnabled(false); + } + } + notifyConfigurationChanged(); + } + + /** + * sets all mandatitory attributes for correct user interaction + * + * @param caption + * the caption of the field + * + * @param tenantDuration + * tenant specific duration value + * @param globalDuration + * duration value which is stored in the global configuration + */ + public void setInitValues(String caption, @NotNull Duration tenantDuration, @NotNull Duration globalDuration) { + this.setCaption(caption); + this.globalDuration = globalDuration; + + this.setValue(tenantDuration); + } + + /** + * sets the allowed range of the duration values + * + * @param minimumDuration + * minimum allowed duration value + * @param maximumDuration + * maximum allowed duration value + */ + public void setAllowedRange(Duration minimumDuration, Duration maximumDuration) { + durationField.setMinimumDuration(minimumDuration); + durationField.setMaximumDuration(maximumDuration); + + } + + /** + * Set the value of the duration field + * + * @param tenantDuration + * duration which will be set in to the duration field, when + * {@code null} the global configuration will be used. + */ + public void setValue(Duration tenantDuration) { + if (tenantDuration == null) { + // no tenant specific configuration + checkBox.setValue(false); + durationField.setDuration(globalDuration); + durationField.setEnabled(false); + } else { + checkBox.setValue(true); + durationField.setDuration(tenantDuration); + durationField.setEnabled(true); + } + } + + /** + * @return the duration of the duration field or null, when the user has + * configured to use the global value. + */ + public Duration getValue() { + if (checkBox.getValue()) { + return durationField.getDuration(); + } + return null; + } + + @Override + public boolean isUserInputValid() { + return !checkBox.getValue() || (durationField.isValid() && durationField.getValue() != null); + } + + private void notifyConfigurationChanged() { + configurationChangeListeners.forEach(listener -> listener.configurationChanged()); + } + + @Override + public void addChangeListener(final ConfigurationGroupChangeListener listener) { + configurationChangeListeners.add(listener); + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java index 7417ddc1b..f5b33354e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java @@ -2,17 +2,27 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.polling; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneId; import java.util.Date; import java.util.Locale; +import java.util.TimeZone; + +import javax.validation.constraints.NotNull; import com.vaadin.data.Property; +import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.data.util.converter.Converter.ConversionException; import com.vaadin.shared.ui.datefield.Resolution; import com.vaadin.ui.DateField; +import com.vaadin.ui.themes.ValoTheme; /** * This class represents a Field which is optimized to enter a time duration in - * form HH:mm:ss (see {@link #DEFAULT_DURATION_FORMAT}). It uses the vaadin + * form HH:mm:ss (see {@link #DURATION_FORMAT_STIRNG}). It uses the vaadin * DateField as a basic element, but the format is optimized for the duration * input. For a correct view of the popup it is recommended not to display the * css-class "v-datefield-calendarpanel-header" and @@ -22,42 +32,61 @@ public class DurationField extends DateField { private static final long serialVersionUID = 1L; - private static String CSS_STYLE_NAME = "durationfield"; + private static final String CSS_STYLE_NAME = "durationfield"; - private static String DEFAULT_DURATION_FORMAT = "HH:mm:ss"; - private static String ADDITIONAL_DURATION_FORMAT = "HHmmss"; + private static final String ADDITIONAL_DURATION_STRING = "HHmmss"; + private static final String DURATION_FORMAT_STIRNG = "HH:mm:ss"; - private SimpleDateFormat default_format = new SimpleDateFormat(DEFAULT_DURATION_FORMAT); - private SimpleDateFormat additional_format = new SimpleDateFormat(ADDITIONAL_DURATION_FORMAT); + private static final ZoneId ZONEID_UTC = ZoneId.of("+0"); + + private static final Duration MAXIMUM_DURATION = Duration.ofHours(23).plusMinutes(59).plusSeconds(59); + + private final SimpleDateFormat durationFormat = new SimpleDateFormat(DURATION_FORMAT_STIRNG); + private final SimpleDateFormat additionalFormat = new SimpleDateFormat(ADDITIONAL_DURATION_STRING); + + private Date minimumDuration; + private Date maximumDuration; /** * Creates a DurationField */ - public DurationField() { + protected DurationField() { + super(); - default_format.setLenient(false); - additional_format.setLenient(false); + this.setTimeZone(TimeZone.getTimeZone(ZONEID_UTC)); + durationFormat.setTimeZone(TimeZone.getTimeZone(ZONEID_UTC)); + additionalFormat.setTimeZone(TimeZone.getTimeZone(ZONEID_UTC)); + durationFormat.setLenient(false); + additionalFormat.setLenient(false); this.setResolution(Resolution.SECOND); - this.setDateFormat(DEFAULT_DURATION_FORMAT); + this.setDateFormat(DURATION_FORMAT_STIRNG); this.addStyleName(CSS_STYLE_NAME); + this.addStyleName(ValoTheme.TEXTFIELD_TINY); + this.setWidth("100px"); // needed that popup shows a 24h clock this.setLocale(Locale.GERMANY); - // adds empty change Listener, but is needed that field reacts on - // pressed enter + this.addValueChangeListener(this); } + /** + * This method is called to handle a non-empty date string from the client + * if the client could not parse it as a Date. In the current case two + * different parsing schemas are tried. If parsing is not possible a + * ConversionException is thrown which marks the DurationField as invalid. + */ @Override protected Date handleUnparsableDateString(String value) throws ConversionException { try { - return default_format.parse(value); + return durationFormat.parse(value); } catch (ParseException e1) { try { - return additional_format.parse(value); + + return additionalFormat.parse("000000".substring(value.length() <= 6 ? value.length() : 6) + value); } catch (ParseException e2) { // if Parsing is not possible ConversionException is thrown } @@ -65,32 +94,128 @@ public class DurationField extends DateField { throw new ConversionException("input is not in HH:MM:SS format."); } - /** - * Sets the duration value as a String - * - * @param duration - * duration as String in format HH:mm:ss, only values <= 23:59:59 - * are excepted - * @throws ParseException - * Exception is thrown, when String parameter is in wrong - * format. - */ - public void setValueAsString(String duration) throws ParseException { - super.setValue(default_format.parse(duration)); - } + @Override + public void valueChange(Property.ValueChangeEvent event) { + // do not delete this method, even when removing the code inside this + // method. This method overwrites the super method, which is + // necessary, that parsing works correctly on pressing enter key - /** - * Gets the duration value as a formated String - * - * @return duration as String in format HH:mm:ss - */ - public String getValueAsString() { - return default_format.format(super.getValue()); + if (event.getProperty() instanceof DurationField) { + Date value = (Date) event.getProperty().getValue(); + + // setValue() calls valueChanged again, when the minimum is greater + // than the maximum this can lead to an endless loop + if (value != null && minimumDuration != null && maximumDuration != null + && minimumDuration.before(maximumDuration)) { + + if (compareTimeOfDates(value, maximumDuration) > 0) { + ((DateField) event.getProperty()).setValue(maximumDuration); + } + + if (compareTimeOfDates(minimumDuration, value) > 0) { + ((DateField) event.getProperty()).setValue(minimumDuration); + } + } + } } @Override - public void valueChange(Property.ValueChangeEvent event) { - // does nothing, but method overrides super methods and is needed that - // parsing works correctly on pressed enter key + public void validate(Date value) throws InvalidValueException { + super.validate(value); + + if (value != null && maximumDuration != null && compareTimeOfDates(value, maximumDuration) > 0) { + throw new InvalidValueException("value is greater than the allowed maximum value"); + } + + if (value != null && minimumDuration != null && compareTimeOfDates(minimumDuration, value) > 0) { + throw new InvalidValueException("value is smaller than the allowed minimum value"); + } + } + + /** + * Sets the duration value + * + * @param duration + * duration, only values <= 23:59:59 are excepted + */ + public void setDuration(@NotNull Duration duration) { + if (duration.compareTo(MAXIMUM_DURATION) > 0) { + throw new IllegalArgumentException("The duaration has to be smaller than 23:59:59."); + } + super.setValue(durationToDate(duration)); + } + + /** + * Gets the duration value of the TextField + * + * @return duration which is written in the vaadin Field + */ + public Duration getDuration() { + if (this.getValue() == null) { + return null; + } + return dateToDuration(this.getValue()); + } + + /** + * Sets the minimal allowed duration value as a String + * + * @param minimumDuration + * minimum Duration, only values smaller 23:59:59 are excepted + */ + public void setMinimumDuration(@NotNull Duration minimumDuration) { + if (minimumDuration.compareTo(MAXIMUM_DURATION) > 0) { + throw new IllegalArgumentException("The minimum duaration has to be smaller than 23:59:59."); + } + this.minimumDuration = durationToDate(minimumDuration); + } + + /** + * Sets the maximum allowed duration value as a String + * + * @param maximumDuration + * maximumDuration, only values smaller 23:59:59 are excepted + */ + public void setMaximumDuration(@NotNull Duration maximumDuration) { + if (maximumDuration.compareTo(MAXIMUM_DURATION) > 0) { + throw new IllegalArgumentException("The maximum duaration has to be smaller than 23:59:59."); + } + this.maximumDuration = durationToDate(maximumDuration); + } + + private static Date durationToDate(final Duration duration) { + if (duration.compareTo(MAXIMUM_DURATION) > 0) { + throw new IllegalArgumentException("The duaration has to be smaller than 23:59:59."); + } + + final LocalTime lt = LocalTime.ofNanoOfDay(duration.toNanos()); + return Date.from(lt.atDate(LocalDate.now(ZONEID_UTC)).atZone(ZONEID_UTC).toInstant()); + } + + private static Duration dateToDuration(final Date date) { + final LocalTime endExclusive = LocalDateTime.ofInstant(date.toInstant(), ZONEID_UTC).toLocalTime(); + return Duration.between(LocalTime.MIDNIGHT, LocalTime.from(endExclusive)); + } + + /** + * Because parsing done by base class returns a different date than parsing + * done by the user or converting duration to a date. But for the + * DurationField comparison only the time is important. This function helps + * comparing the time and ignores the values for day, month and year. + * + * @param d1 + * date, which time will compared with the time of d2 + * @param d2 + * date, which time will compared with the time of d1 + * @return the value 0 if the time represented d1 is equal to the time + * represented by d2; a value less than 0 if the time of d1 is + * before the time of d2; and a value greater than 0 if the time of + * d1 is after the time represented by d2. + */ + private int compareTimeOfDates(Date d1, Date d2) { + LocalTime lt1 = LocalDateTime.ofInstant(d1.toInstant(), ZONEID_UTC).toLocalTime(); + LocalTime lt2 = LocalDateTime.ofInstant(d2.toInstant(), ZONEID_UTC).toLocalTime(); + + return lt1.compareTo(lt2); } } diff --git a/hawkbit-ui/src/main/resources/messages.properties b/hawkbit-ui/src/main/resources/messages.properties index 209569ff0..27103a0b9 100644 --- a/hawkbit-ui/src/main/resources/messages.properties +++ b/hawkbit-ui/src/main/resources/messages.properties @@ -400,6 +400,7 @@ configuration.authentication.title=Authentication Configuration configuration.polling.title=Polling Configuration configuration.polling.time=Polling Time configuration.polling.overduetime=Polling Overdue Time +configuration.polling.custom.value=use a custom value #Calendar calendar.year=year From 3f451537cf2fcf9d5b587b5178ab26fcedf3f8c9 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Mon, 18 Jan 2016 11:11:01 +0100 Subject: [PATCH 07/42] Added tests for PollConfigurationHelper Signed-off-by: Nonnenmacher Fabian --- .../PollConfigurationHelperTest.java | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java new file mode 100644 index 000000000..21bba6cf7 --- /dev/null +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java @@ -0,0 +1,151 @@ +package org.eclipse.hawkbit.repository; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.time.Duration; + +import org.eclipse.hawkbit.ControllerPollProperties; +import org.eclipse.hawkbit.repository.model.TenantMetaData; +import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class PollConfigurationHelperTest { + + @Mock + private ControllerPollProperties controllerPollProperties; + + @Mock + private SystemManagement systemManagement; + + @Mock + private TenantMetaData tenantMetaData; + + private PollConfigurationHelper pollConfigurationHelperUnderTest; + + private static final Duration DEFAULT_MIN = Duration.ofSeconds(30); + private static final Duration DEFAULT_MAX = Duration.ofHours(23).plusMinutes(59).plusSeconds(59); + private static final Duration DEFAULT_POLLING = Duration.ofMinutes(5); + private static final Duration DEFAULT_OVERDUE = Duration.ofMinutes(5); + + @Before + public void initMocks() { + + pollConfigurationHelperUnderTest = PollConfigurationHelper.getInstance(); + + setConfigurationValues("00:05:00", "00:05:00", "00:00:30", "23:59:59"); + setTenantConfiguration(null, null); + } + + private void setConfigurationValues(String polling, String overdue, String min, String max) { + when(controllerPollProperties.getPollingTime()).thenReturn(polling); + when(controllerPollProperties.getPollingOverdueTime()).thenReturn(overdue); + when(controllerPollProperties.getMinPollingTime()).thenReturn(min); + when(controllerPollProperties.getMaxPollingTime()).thenReturn(max); + + pollConfigurationHelperUnderTest.setControllerPollProperties(controllerPollProperties); + pollConfigurationHelperUnderTest.initializeConfigurationValues(); + } + + private void setTenantConfiguration(String polling, String overdue) { + + when(tenantMetaData.getPollingTime()).thenReturn(polling); + when(tenantMetaData.getPollingOverdueTime()).thenReturn(overdue); + + when(systemManagement.getTenantMetadata()).thenReturn(tenantMetaData); + + pollConfigurationHelperUnderTest.setSystemManagement(systemManagement); + } + + @Test + public void getCorrectConfigurationValues() { + + setConfigurationValues("00:08:00", "00:12:00", "00:01:00", "20:00:00"); + + assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(Duration.ofHours(20)); + assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(Duration.ofMinutes(1)); + assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(Duration.ofMinutes(8)); + assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()) + .isEqualTo(Duration.ofMinutes(12)); + + assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(Duration.ofMinutes(8)); + assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(12)); + } + + @Test + public void getWrongFromattedConfiguratonValues() { + setConfigurationValues("00-08:00", "abc", "12:00:000", "20hours"); + + assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(DEFAULT_MAX); + assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(DEFAULT_MIN); + assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(DEFAULT_POLLING); + assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); + } + + @Test + public void getMinimumGreaterMaximum() { + setConfigurationValues("00:07:00", "00:07:00", "01:00:00", "00:00:00"); + + assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(DEFAULT_MAX); + assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(DEFAULT_MIN); + assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(Duration.ofMinutes(7)); + assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()) + .isEqualTo(Duration.ofMinutes(7)); + } + + @Test + public void getPollConfigurationNotWithinRange() { + setConfigurationValues("22:00:00", "00:07:00", "01:00:00", "10:00:00"); + + assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(Duration.ofHours(10)); + assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(Duration.ofHours(1)); + assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(DEFAULT_POLLING); + assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); + } + + @Test + public void getPollingValuesFromTenant() { + + setTenantConfiguration("00:11:00", "00:13:00"); + + assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(Duration.ofMinutes(11)); + assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(13)); + + } + + @Test + public void getInvalidPollingValuesFromTenant() { + + setTenantConfiguration("00:00:01", "00:130:00"); + + assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(DEFAULT_POLLING); + assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); + + } + + @Test + public void setTenantConfiguration() { + pollConfigurationHelperUnderTest.setTenantPollTimeIntervall(Duration.ofHours(3).plusSeconds(3)); + pollConfigurationHelperUnderTest.setTenantOverduePollTimeIntervall(Duration.ofMinutes(7).plusSeconds(7)); + + verify(tenantMetaData, times(1)).setPollingTime("03:00:03"); + verify(tenantMetaData, times(1)).setPollingOverdueTime("00:07:07"); + } + + @Test + public void setTenantConfigurationToNull() { + pollConfigurationHelperUnderTest.setTenantPollTimeIntervall(null); + pollConfigurationHelperUnderTest.setTenantOverduePollTimeIntervall(null); + + verify(tenantMetaData, times(1)).setPollingTime(null); + verify(tenantMetaData, times(1)).setPollingOverdueTime(null); + } + +} From 4675ebf22cf515b1d4a8fe013ba7bc5b15927f19 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 19 Jan 2016 15:29:12 +0100 Subject: [PATCH 08/42] Refactoring of Authentification UI * modified AuthentificationUI to use same Interface as Polling Configuration UI * renaming of Interface "ConfigurationElement" -> "ConfigurationItem" Signed-off-by: Nonnenmacher Fabian --- .../AuthenticationConfigurationView.java | 12 ++++---- .../BaseConfigurationView.java | 6 ++-- .../ConfigurationGroup.java | 2 +- ...ionElement.java => ConfigurationItem.java} | 8 +++--- .../PollingConfigurationView.java | 5 ++-- .../TenantConfigurationDashboardView.java | 6 ++-- ...AuthenticationTenantConfigurationItem.java | 15 +++++++--- ...a => AuthenticationConfigurationItem.java} | 28 ++----------------- .../polling/DurationConfigField.java | 10 +++---- 9 files changed, 38 insertions(+), 54 deletions(-) rename hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/{ConfigurationElement.java => ConfigurationItem.java} (76%) rename hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/{TenantConfigurationItem.java => AuthenticationConfigurationItem.java} (55%) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java index ea228bbc7..e440251c9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java @@ -11,10 +11,10 @@ package org.eclipse.hawkbit.ui.tenantconfiguration; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; +import org.eclipse.hawkbit.ui.tenantconfiguration.authentication.AuthenticationConfigurationItem; import org.eclipse.hawkbit.ui.tenantconfiguration.authentication.CertificateAuthenticationConfigurationItem; import org.eclipse.hawkbit.ui.tenantconfiguration.authentication.GatewaySecurityTokenAuthenticationConfigurationItem; import org.eclipse.hawkbit.ui.tenantconfiguration.authentication.TargetSecurityTokenAuthenticationConfigurationItem; -import org.eclipse.hawkbit.ui.tenantconfiguration.authentication.TenantConfigurationItem; import org.eclipse.hawkbit.ui.utils.I18N; import org.springframework.beans.factory.annotation.Autowired; @@ -37,7 +37,7 @@ import com.vaadin.ui.VerticalLayout; @SpringComponent @ViewScope public class AuthenticationConfigurationView extends BaseConfigurationView - implements ConfigurationGroup, TenantConfigurationItem.TenantConfigurationChangeListener, ValueChangeListener { + implements ConfigurationGroup, ConfigurationItem.ConfigurationItemChangeListener, ValueChangeListener { /** * @@ -95,14 +95,14 @@ public class AuthenticationConfigurationView extends BaseConfigurationView certificateAuthCheckbox = SPUIComponentProvider.getCheckBox("", DIST_CHECKBOX_STYLE, null, false, ""); certificateAuthCheckbox.setValue(certificateAuthenticationConfigurationItem.isConfigEnabled()); certificateAuthCheckbox.addValueChangeListener(this); - certificateAuthenticationConfigurationItem.addConfigurationChangeListener(this); + certificateAuthenticationConfigurationItem.addChangeListener(this); gridLayout.addComponent(certificateAuthCheckbox, 0, 0); gridLayout.addComponent(certificateAuthenticationConfigurationItem, 1, 0); targetSecTokenCheckBox = SPUIComponentProvider.getCheckBox("", DIST_CHECKBOX_STYLE, null, false, ""); targetSecTokenCheckBox.setValue(targetSecurityTokenAuthenticationConfigurationItem.isConfigEnabled()); targetSecTokenCheckBox.addValueChangeListener(this); - targetSecurityTokenAuthenticationConfigurationItem.addConfigurationChangeListener(this); + targetSecurityTokenAuthenticationConfigurationItem.addChangeListener(this); gridLayout.addComponent(targetSecTokenCheckBox, 0, 1); gridLayout.addComponent(targetSecurityTokenAuthenticationConfigurationItem, 1, 1); @@ -110,7 +110,7 @@ public class AuthenticationConfigurationView extends BaseConfigurationView gatewaySecTokenCheckBox.setId("gatewaysecuritycheckbox"); gatewaySecTokenCheckBox.setValue(gatewaySecurityTokenAuthenticationConfigurationItem.isConfigEnabled()); gatewaySecTokenCheckBox.addValueChangeListener(this); - gatewaySecurityTokenAuthenticationConfigurationItem.addConfigurationChangeListener(this); + gatewaySecurityTokenAuthenticationConfigurationItem.addChangeListener(this); gridLayout.addComponent(gatewaySecTokenCheckBox, 0, 2); gridLayout.addComponent(gatewaySecurityTokenAuthenticationConfigurationItem, 1, 2); @@ -168,7 +168,7 @@ public class AuthenticationConfigurationView extends BaseConfigurationView notifyConfigurationChanged(); CheckBox checkBox = (CheckBox) event.getProperty(); - TenantConfigurationItem configurationItem = null; + AuthenticationConfigurationItem configurationItem = null; if (checkBox == gatewaySecTokenCheckBox) { configurationItem = gatewaySecurityTokenAuthenticationConfigurationItem; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java index 11cc7d2a6..a3f313414 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java @@ -15,14 +15,14 @@ public abstract class BaseConfigurationView extends CustomComponent implements C private static final long serialVersionUID = 1L; - private final List configurationChangeListeners = new ArrayList<>(); + private final List configurationChangeListeners = new ArrayList<>(); protected void notifyConfigurationChanged() { - configurationChangeListeners.forEach(listener -> listener.configurationChanged()); + configurationChangeListeners.forEach(listener -> listener.configurationHasChanged()); } @Override - public void addChangeListener(final ConfigurationGroupChangeListener listener) { + public void addChangeListener(final ConfigurationItemChangeListener listener) { configurationChangeListeners.add(listener); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java index 1d2245394..90a38dd56 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationGroup.java @@ -15,7 +15,7 @@ import com.vaadin.ui.Component; * * */ -public interface ConfigurationGroup extends Component, ConfigurationElement { +public interface ConfigurationGroup extends Component, ConfigurationItem { /** * called to store any configuration changes. diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationElement.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java similarity index 76% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationElement.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java index 7614f852f..746d52ca5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationElement.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java @@ -2,7 +2,7 @@ package org.eclipse.hawkbit.ui.tenantconfiguration; import java.io.Serializable; -public interface ConfigurationElement { +public interface ConfigurationItem { /** * called to verify that the Input done by the user is valid @@ -19,17 +19,17 @@ public interface ConfigurationElement { * the listener to be notified in case the item changes some * configuration */ - void addChangeListener(ConfigurationGroupChangeListener listener); + void addChangeListener(final ConfigurationItemChangeListener listener); /** * Configuration Change Listener to be notified about configuration changes * in configuration group. * */ - interface ConfigurationGroupChangeListener extends Serializable { + interface ConfigurationItemChangeListener extends Serializable { /** * called to notify about configuration has been changed. */ - void configurationChanged(); + void configurationHasChanged(); } } \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index b57c960a2..3363f1d23 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -24,7 +24,7 @@ import com.vaadin.ui.VerticalLayout; @SpringComponent @ViewScope public class PollingConfigurationView extends BaseConfigurationView - implements ConfigurationGroup, ConfigurationElement.ConfigurationGroupChangeListener { + implements ConfigurationGroup, ConfigurationItem.ConfigurationItemChangeListener { private static final long serialVersionUID = 1L; @@ -97,6 +97,7 @@ public class PollingConfigurationView extends BaseConfigurationView tenantPollingOverdueTime = fieldPollingOverdueTime.getValue(); pollConfigurationHelper.setTenantOverduePollTimeIntervall(fieldPollingOverdueTime.getValue()); } + } @Override @@ -111,7 +112,7 @@ public class PollingConfigurationView extends BaseConfigurationView } @Override - public void configurationChanged() { + public void configurationHasChanged() { notifyConfigurationChanged(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java index b8873a5bb..d98aa8916 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java @@ -17,7 +17,7 @@ import org.eclipse.hawkbit.ui.HawkbitUI; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; -import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationElement.ConfigurationGroupChangeListener; +import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationItem.ConfigurationItemChangeListener; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; import org.eclipse.hawkbit.ui.utils.UINotification; @@ -45,7 +45,7 @@ import com.vaadin.ui.VerticalLayout; @SpringView(name = TenantConfigurationDashboardView.VIEW_NAME, ui = HawkbitUI.class) @ViewScope public class TenantConfigurationDashboardView extends CustomComponent - implements View, ConfigurationGroupChangeListener { + implements View, ConfigurationItemChangeListener { public static final String VIEW_NAME = "spSystemConfig"; private static final long serialVersionUID = 1L; @@ -168,7 +168,7 @@ public class TenantConfigurationDashboardView extends CustomComponent * ConfigurationGroupChangeListener #configurationChanged() */ @Override - public void configurationChanged() { + public void configurationHasChanged() { saveConfigurationBtn.setEnabled(true); undoConfigurationBtn.setEnabled(true); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java index 05d581267..aae5c592d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java @@ -25,7 +25,8 @@ import com.vaadin.ui.VerticalLayout; * * */ -abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLayout implements TenantConfigurationItem { +abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLayout + implements AuthenticationConfigurationItem { /** * @@ -35,7 +36,7 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay private final TenantConfigurationKey configurationKey; private final transient SystemManagement systemManagement; - private final List configurationChangeListeners = new ArrayList<>(); + private final List configurationChangeListeners = new ArrayList<>(); /** * @param configurationKey @@ -65,7 +66,8 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay */ @Override public boolean isConfigEnabled() { - return systemManagement.getConfigurationValue(configurationKey, Boolean.class); + boolean b = systemManagement.getConfigurationValue(configurationKey, Boolean.class); + return b; } /** @@ -95,7 +97,12 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay * TenantConfigurationChangeListener) */ @Override - public void addConfigurationChangeListener(final TenantConfigurationChangeListener listener) { + public void addChangeListener(final ConfigurationItemChangeListener listener) { configurationChangeListeners.add(listener); } + + @Override + public boolean isUserInputValid() { + return true; + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TenantConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AuthenticationConfigurationItem.java similarity index 55% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TenantConfigurationItem.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AuthenticationConfigurationItem.java index 911520e99..b6b045e1b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TenantConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AuthenticationConfigurationItem.java @@ -8,7 +8,7 @@ */ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; -import java.io.Serializable; +import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationItem; import com.vaadin.ui.Component; @@ -20,7 +20,7 @@ import com.vaadin.ui.Component; * * */ -public interface TenantConfigurationItem extends Component { +public interface AuthenticationConfigurationItem extends Component, ConfigurationItem { /** * @return {@code true} if configuration is enabled, otherwise {@code false} @@ -47,28 +47,4 @@ public interface TenantConfigurationItem extends Component { */ void undo(); - /** - * Adds a configuration change listener to notify about configuration - * changes. - * - * @param listener - * the listener to be notified in case the item changes some - * configuration - */ - void addConfigurationChangeListener(TenantConfigurationChangeListener listener); - - /** - * Configuration Change Listener to be notified about configuration changes - * in configuration item. - * - * - * - */ - @FunctionalInterface - interface TenantConfigurationChangeListener extends Serializable { - /** - * called to notify about configuration has been changed. - */ - void configurationHasChanged(); - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index 5555037a6..a16accbae 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -8,7 +8,7 @@ import javax.annotation.PostConstruct; import javax.validation.constraints.NotNull; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationElement; +import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationItem; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.springframework.beans.factory.annotation.Autowired; @@ -32,11 +32,11 @@ import com.vaadin.ui.Label; @SpringComponent @ViewScope @Scope("prototype") -public class DurationConfigField extends GridLayout implements ValueChangeListener, ConfigurationElement { +public class DurationConfigField extends GridLayout implements ValueChangeListener, ConfigurationItem { private static final long serialVersionUID = 1L; - private final List configurationChangeListeners = new ArrayList<>(); + private final List configurationChangeListeners = new ArrayList<>(); private CheckBox checkBox; private DurationField durationField; @@ -171,11 +171,11 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen } private void notifyConfigurationChanged() { - configurationChangeListeners.forEach(listener -> listener.configurationChanged()); + configurationChangeListeners.forEach(listener -> listener.configurationHasChanged()); } @Override - public void addChangeListener(final ConfigurationGroupChangeListener listener) { + public void addChangeListener(final ConfigurationItemChangeListener listener) { configurationChangeListeners.add(listener); } } From 088df73ea93c255d951be79c23afeecb80c3aa28 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 19 Jan 2016 16:41:13 +0100 Subject: [PATCH 09/42] Refactoring of buisness logic * added DurationHelper to have access to Convertion in every class * removed tenant specific getter and setter from PollConfigurationHelper * changed getter and setter in TenantMetaData to use DurationObjects instead of Strings * updated UI to call new functions * updated module tests Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/ControllerPollProperties.java | 2 +- .../repository/model/TenantMetaData.java | 22 ++- .../model/helper/DurationHelper.java | 70 +++++++++ .../model/helper/PollConfigurationHelper.java | 143 ++++-------------- .../PollConfigurationHelperTest.java | 38 +++-- .../PollingConfigurationView.java | 24 ++- 6 files changed, 152 insertions(+), 147 deletions(-) create mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java index 1c19b35d0..51a4f9ff1 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java @@ -21,7 +21,7 @@ public class ControllerPollProperties { private String pollingTime = "00:05:00"; private String pollingOverdueTime = "00:05:00"; private String maxPollingTime = "23:59:00"; - private String minPollingTime = "23:59:00"; + private String minPollingTime = "00:00:30"; public String getPollingTime() { return pollingTime; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java index 4e47f856d..a83004ead 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.repository.model; import java.io.Serializable; +import java.time.Duration; import javax.persistence.Access; import javax.persistence.AccessType; @@ -24,9 +25,11 @@ import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; +import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import javax.persistence.Version; +import org.eclipse.hawkbit.repository.model.helper.DurationHelper; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; @@ -83,6 +86,9 @@ public class TenantMetaData implements Serializable { // "fk_tenant_md_default_ds_type" ) private DistributionSetType defaultDsType; + @Transient + private DurationHelper dh = new DurationHelper(); + public TenantMetaData() { } @@ -262,19 +268,19 @@ public class TenantMetaData implements Serializable { return true; } - public String getPollingTime() { - return pollingTime; + public Duration getPollingTime() { + return dh.formattedStringToDuration(pollingTime); } - public void setPollingTime(String pollingTime) { - this.pollingTime = pollingTime; + public void setPollingTime(Duration pollingTime) { + this.pollingTime = dh.durationToFormattedString(pollingTime); } - public String getPollingOverdueTime() { - return pollingOverdueTime; + public Duration getPollingOverdueTime() { + return dh.formattedStringToDuration(pollingOverdueTime); } - public void setPollingOverdueTime(String pollingOverdueTime) { - this.pollingOverdueTime = pollingOverdueTime; + public void setPollingOverdueTime(Duration pollingOverdueTime) { + this.pollingOverdueTime = dh.durationToFormattedString(pollingOverdueTime); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java new file mode 100644 index 000000000..d14752f8f --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java @@ -0,0 +1,70 @@ +package org.eclipse.hawkbit.repository.model.helper; + +import java.time.Duration; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.TemporalAccessor; + +/** + * This class is a helper for converting a duration into a string and for the + * other way. The string is in the format expected in configuration and database + * {@link #DURATION_FORMAT}. + * + */ +public class DurationHelper { + + /** + * Format of the String expected in configuration file and in the databse. + */ + public static final String DURATION_FORMAT = "HH:mm:ss"; + + /** + * Converts a Duration into a formatted String + * + * @param duration + * duration, which will be converted into a formatted String + * @return String in the duration format, specified at + * {@link #DURATION_FORMAT} + */ + public String durationToFormattedString(Duration duration) { + if (duration == null) { + return null; + } + + return LocalTime.ofNanoOfDay(duration.toNanos()).format(DateTimeFormatter.ofPattern(DURATION_FORMAT)); + } + + /** + * Converts a formatted Sting into a Duration object. + * + * @param formattedDuration + * String in {@link #DURATION_FORMAT} + * @return duration + * @throws DateTimeParseException + * when String is in wrong format + */ + public Duration formattedStringToDuration(String formattedDuration) throws DateTimeParseException { + if (formattedDuration == null) { + return null; + } + + final TemporalAccessor ta = DateTimeFormatter.ofPattern(DURATION_FORMAT).parse(formattedDuration.trim()); + return Duration.between(LocalTime.MIDNIGHT, LocalTime.from(ta)); + } + + /** + * converts values of time constants to a Duration object.. + * + * @param hours + * count of hours + * @param minutes + * count of minutes + * @param seconds + * count of seconds + * @return duration + */ + public Duration getDurationByTimeValues(long hours, long minutes, long seconds) { + return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java index 9b9d24de9..55f9395b0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java @@ -9,10 +9,7 @@ package org.eclipse.hawkbit.repository.model.helper; import java.time.Duration; -import java.time.LocalTime; -import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; -import java.time.temporal.TemporalAccessor; import javax.annotation.PostConstruct; import javax.validation.constraints.NotNull; @@ -38,7 +35,6 @@ public final class PollConfigurationHelper { * Format of the expected Duration String. Pattern has to be in Valid Format * for SimpleDateFormat */ - public static final String DURATION_FORMAT = "HH:mm:ss"; private static final Logger LOG = LoggerFactory.getLogger(PollConfigurationHelper.class); private static final PollConfigurationHelper INSTANCE = new PollConfigurationHelper(); @@ -59,6 +55,8 @@ public final class PollConfigurationHelper { private static final int DEFAULT_MIN_MINUTE = 0; private static final int DEFAULT_MIN_SECOND = 30; + private static DurationHelper dh = new DurationHelper(); + @Autowired private ControllerPollProperties controllerPollProperties; @@ -91,32 +89,33 @@ public final class PollConfigurationHelper { private void readGlobalDurationsFromConfiguration() { try { - configurationMaximumPollTime = formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); + configurationMaximumPollTime = dh.formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); } catch (DateTimeParseException e) { // Set to default values - configurationMaximumPollTime = getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, + configurationMaximumPollTime = dh.getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, DEFAULT_MAX_SECOND); } try { - configurationMinimumPollTime = formattedStringToDuration(controllerPollProperties.getMinPollingTime()); + configurationMinimumPollTime = dh.formattedStringToDuration(controllerPollProperties.getMinPollingTime()); } catch (DateTimeParseException e) { // Set to default values - configurationMinimumPollTime = getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, + configurationMinimumPollTime = dh.getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, DEFAULT_MIN_SECOND); } try { - configurationPollTime = formattedStringToDuration(controllerPollProperties.getPollingTime()); + configurationPollTime = dh.formattedStringToDuration(controllerPollProperties.getPollingTime()); } catch (DateTimeParseException e) { - configurationPollTime = getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, + configurationPollTime = dh.getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, DEFAULT_POLL_SECOND); } try { - configurationOverduePollTime = formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); + configurationOverduePollTime = dh + .formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); } catch (DateTimeParseException e) { - configurationOverduePollTime = getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, + configurationOverduePollTime = dh.getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, DEFAULT_OVERDUE_SECOND); } @@ -129,27 +128,26 @@ public final class PollConfigurationHelper { LOG.warn("The configured maximum value of the polling time is smaller" + " than the configured minimum value. Both are replaced by default values."); - configurationMaximumPollTime = getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, + configurationMaximumPollTime = dh.getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, DEFAULT_MAX_SECOND); - configurationMinimumPollTime = getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, + configurationMinimumPollTime = dh.getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, DEFAULT_MIN_SECOND); } if (!isWithinRange(configurationPollTime)) { // poll time value not within allowed range ==> use default value - configurationPollTime = getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, + configurationPollTime = dh.getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, DEFAULT_POLL_SECOND); } if (!isWithinRange(configurationOverduePollTime)) { // overdue poll time value not within range => use default value - configurationOverduePollTime = getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, + configurationOverduePollTime = dh.getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, DEFAULT_OVERDUE_SECOND); } } private boolean isWithinRange(@NotNull Duration duration) { - return duration.compareTo(configurationMinimumPollTime) > 0 && duration.compareTo(configurationMaximumPollTime) < 0; } @@ -161,24 +159,19 @@ public final class PollConfigurationHelper { * the default value which is {@code 00:05:00} never {@code null}. */ public Duration getPollTimeInterval() { - Duration tenantPollTimeInterval = getTenantPollTimeIntervall(); + Duration tenantPollTimeInterval = systemManagement.getTenantMetadata().getPollingTime(); if (tenantPollTimeInterval != null) { - return tenantPollTimeInterval; + if (isWithinRange(tenantPollTimeInterval)) { + return tenantPollTimeInterval; + } + LOG.warn( + "Tenant {} has stored a pollign interval {} which is not in the allowed range. Configured default value is loaded.", + systemManagement.currentTenant(), tenantPollTimeInterval); } return configurationPollTime; } - /** - * @return the poll time interval stored in the tenant meta data. If there - * is no value stored this function returns {@code null} - */ - public Duration getTenantPollTimeIntervall() { - String tenantPollingTime = systemManagement.getTenantMetadata().getPollingTime(); - - return validateDurationStringAndGetDuration(tenantPollingTime, "polling time"); - } - /** * @return the poll time interval configured in the configuration * {@code hawkbit.server.controller.polling} or the default value @@ -189,23 +182,6 @@ public final class PollConfigurationHelper { return configurationPollTime; } - /** - * Stores the changed value in the tenant meta data configuration. The value - * {@code null} is clearly allowed. Setting the poll time to {@code null} - * means no specific tenant configuration and global configuration are used. - * - * @param pollingTime - * polling time interval as formatted string {@code HH:mm:ss} or - * {@code null} - */ - public void setTenantPollTimeIntervall(Duration pollingTime) { - if (pollingTime == null) { - systemManagement.getTenantMetadata().setPollingTime(null); - return; - } - systemManagement.getTenantMetadata().setPollingTime(durationToFormattedString(pollingTime)); - } - /** * @return the overdue poll time interval stored in the tenant meta data. If * there is no tenant specific configuration the global value, @@ -214,46 +190,19 @@ public final class PollConfigurationHelper { * which is {@code 00:05:00} never {@code null}. */ public Duration getOverduePollTimeInterval() { - Duration tenantOverduePollTimeInterval = getTenantOverduePollTimeIntervall(); + Duration tenantOverduePollTimeInterval = systemManagement.getTenantMetadata().getPollingOverdueTime(); if (tenantOverduePollTimeInterval != null) { - return tenantOverduePollTimeInterval; + if (isWithinRange(tenantOverduePollTimeInterval)) { + return tenantOverduePollTimeInterval; + } + LOG.warn( + "Tenant {} has stored an overdue polling interval {} which is not in the allowed range. Configured default value is loaded.", + systemManagement.currentTenant(), tenantOverduePollTimeInterval); } return configurationOverduePollTime; }; - /** - * @return the poll time interval stored in the tenant meta data. If there - * is no value stored this function returns {@code null} - */ - public Duration getTenantOverduePollTimeIntervall() { - String tenantOverduePollingTime = systemManagement.getTenantMetadata().getPollingOverdueTime(); - - return validateDurationStringAndGetDuration(tenantOverduePollingTime, "overdue polling time"); - } - - private Duration validateDurationStringAndGetDuration(String pollingTime, String paramNameForLog) { - if (pollingTime == null) { - return null; - } - - try { - Duration d = formattedStringToDuration(pollingTime); - - if (isWithinRange(d)) { - return d; - } - - LOG.warn("Tenant {} has stored a {} {} which is not in the allowed range.", - systemManagement.currentTenant(), paramNameForLog, pollingTime); - - } catch (DateTimeParseException ex) { - LOG.warn("Tenant {} has stored an invalid {} {} in its meta data.", systemManagement.currentTenant(), - paramNameForLog, pollingTime); - } - return null; - } - /** * @return the overdue poll time interval configured in the configuration * {@code hawkbit.server.controller.polling.overdue} or the default @@ -263,25 +212,6 @@ public final class PollConfigurationHelper { return configurationOverduePollTime; } - /** - * Stores the polling overtime interval value in the tenant meta data - * configuration. The value {@code null} is clearly allowed. Setting the - * overdue poll time to {@code null} means no specific tenant configuration - * and global configuration are used. - * - * @param pollingTime - * polling time interval as formatted string {@code HH:mm:ss} or - * {@code null} - */ - public void setTenantOverduePollTimeIntervall(Duration pollingTime) { - if (pollingTime == null) { - systemManagement.getTenantMetadata().setPollingOverdueTime(null); - return; - } - - systemManagement.getTenantMetadata().setPollingOverdueTime(durationToFormattedString(pollingTime)); - } - /** * @return the maximum poll time duration configured in the configuration * {@code hawkbit.server.controller.polling.overdue} or the default @@ -300,26 +230,13 @@ public final class PollConfigurationHelper { return configurationMinimumPollTime; } - private String durationToFormattedString(@NotNull Duration duration) { - return LocalTime.ofNanoOfDay(duration.toNanos()).format(DateTimeFormatter.ofPattern(DURATION_FORMAT)); - } - - private Duration formattedStringToDuration(String formattedDuration) throws DateTimeParseException { - final TemporalAccessor ta = DateTimeFormatter.ofPattern(DURATION_FORMAT).parse(formattedDuration.trim()); - return Duration.between(LocalTime.MIDNIGHT, LocalTime.from(ta)); - } - - private Duration getDurationByTimeValues(long hours, long minutes, long seconds) { - return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); - } - /** * sets the ControllerPollProperties in a not spring handled context. Don't * forget to call {@code initializeConfigurationValues} afterwards to read * the values from the PollProperties. * * @param controllerPollProperties - * the controll properties + * the controller poll properties */ public void setControllerPollProperties(ControllerPollProperties controllerPollProperties) { this.controllerPollProperties = controllerPollProperties; diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java index 21bba6cf7..4ee6e92f9 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java @@ -1,14 +1,13 @@ package org.eclipse.hawkbit.repository; import static org.fest.assertions.api.Assertions.assertThat; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.time.Duration; import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.repository.model.TenantMetaData; +import org.eclipse.hawkbit.repository.model.helper.DurationHelper; import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; import org.junit.Before; import org.junit.Test; @@ -54,7 +53,7 @@ public class PollConfigurationHelperTest { pollConfigurationHelperUnderTest.initializeConfigurationValues(); } - private void setTenantConfiguration(String polling, String overdue) { + private void setTenantConfiguration(Duration polling, Duration overdue) { when(tenantMetaData.getPollingTime()).thenReturn(polling); when(tenantMetaData.getPollingOverdueTime()).thenReturn(overdue); @@ -113,17 +112,17 @@ public class PollConfigurationHelperTest { @Test public void getPollingValuesFromTenant() { - setTenantConfiguration("00:11:00", "00:13:00"); + setTenantConfiguration(Duration.ofMinutes(11), Duration.ofMinutes(17)); assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(Duration.ofMinutes(11)); - assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(13)); + assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(17)); } @Test public void getInvalidPollingValuesFromTenant() { - setTenantConfiguration("00:00:01", "00:130:00"); + setTenantConfiguration(Duration.ZERO, Duration.ofHours(30)); assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(DEFAULT_POLLING); assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); @@ -131,21 +130,18 @@ public class PollConfigurationHelperTest { } @Test - public void setTenantConfiguration() { - pollConfigurationHelperUnderTest.setTenantPollTimeIntervall(Duration.ofHours(3).plusSeconds(3)); - pollConfigurationHelperUnderTest.setTenantOverduePollTimeIntervall(Duration.ofMinutes(7).plusSeconds(7)); + public void basicTestingOfDurationHelper() { + DurationHelper dh = new DurationHelper(); + + assertThat(dh.durationToFormattedString(null)).isNull(); + assertThat(dh.durationToFormattedString(Duration.ofHours(1).plusMinutes(2).plusSeconds(1))) + .isEqualTo("01:02:01"); + + assertThat(dh.formattedStringToDuration(null)).isNull(); + assertThat(dh.formattedStringToDuration("01:02:01")) + .isEqualTo(Duration.ofHours(1).plusMinutes(2).plusSeconds(1)); + + assertThat(dh.getDurationByTimeValues(0, 0, 0)).isEqualTo(Duration.ZERO); - verify(tenantMetaData, times(1)).setPollingTime("03:00:03"); - verify(tenantMetaData, times(1)).setPollingOverdueTime("00:07:07"); } - - @Test - public void setTenantConfigurationToNull() { - pollConfigurationHelperUnderTest.setTenantPollTimeIntervall(null); - pollConfigurationHelperUnderTest.setTenantOverduePollTimeIntervall(null); - - verify(tenantMetaData, times(1)).setPollingTime(null); - verify(tenantMetaData, times(1)).setPollingOverdueTime(null); - } - } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 3363f1d23..537e839ba 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -4,6 +4,8 @@ import java.time.Duration; import javax.annotation.PostConstruct; +import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; import org.eclipse.hawkbit.ui.tenantconfiguration.polling.DurationConfigField; import org.eclipse.hawkbit.ui.utils.I18N; @@ -34,6 +36,9 @@ public class PollingConfigurationView extends BaseConfigurationView @Autowired PollConfigurationHelper pollConfigurationHelper; + @Autowired + private transient SystemManagement systemManagement; + @Autowired private DurationConfigField fieldPollingTime; @@ -61,7 +66,9 @@ public class PollingConfigurationView extends BaseConfigurationView headerDisSetType.addStyleName("config-panel-header"); vLayout.addComponent(headerDisSetType); - tenantPollingTime = pollConfigurationHelper.getTenantPollTimeIntervall(); + final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + + tenantPollingTime = tenantMetaData.getPollingTime(); fieldPollingTime.setInitValues(i18n.get("configuration.polling.time"), tenantPollingTime, pollConfigurationHelper.getGlobalPollTimeInterval()); fieldPollingTime.setAllowedRange(pollConfigurationHelper.getMinimumPollingInterval(), @@ -70,7 +77,7 @@ public class PollingConfigurationView extends BaseConfigurationView vLayout.addComponent(fieldPollingTime); - tenantPollingOverdueTime = pollConfigurationHelper.getTenantOverduePollTimeIntervall(); + tenantPollingOverdueTime = tenantMetaData.getPollingOverdueTime(); fieldPollingOverdueTime.setInitValues(i18n.get("configuration.polling.overduetime"), tenantPollingOverdueTime, pollConfigurationHelper.getGlobalOverduePollTimeInterval()); @@ -88,16 +95,25 @@ public class PollingConfigurationView extends BaseConfigurationView public void save() { // make sure values are only saved, when the value has been changed + boolean hasChanged = false; + + final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + if (!compareDurations(tenantPollingTime, fieldPollingTime.getValue())) { tenantPollingTime = fieldPollingTime.getValue(); - pollConfigurationHelper.setTenantPollTimeIntervall(fieldPollingTime.getValue()); + tenantMetaData.setPollingTime(fieldPollingTime.getValue()); + hasChanged = true; } if (!compareDurations(tenantPollingOverdueTime, fieldPollingOverdueTime.getValue())) { tenantPollingOverdueTime = fieldPollingOverdueTime.getValue(); - pollConfigurationHelper.setTenantOverduePollTimeIntervall(fieldPollingOverdueTime.getValue()); + tenantMetaData.setPollingOverdueTime(fieldPollingOverdueTime.getValue()); + hasChanged = true; } + if (hasChanged) { + systemManagement.updateTenantMetadata(tenantMetaData); + } } @Override From f3fa085c623ed182ea8a277d6071b2929ef29208 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 21 Jan 2016 15:29:10 +0100 Subject: [PATCH 10/42] First implemtation of REST-API Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/exception/SpServerError.java | 13 ++ .../hawkbit/repository/SystemManagement.java | 31 +++ .../InvalidDistributionSetTypeException.java | 40 ++++ .../InvalidPollingTimeException.java | 35 ++++ .../hawkbit/rest/resource/RestConstants.java | 2 + ...a => AuthenticationConfigurationRest.java} | 2 +- .../SystemConfigurationRequestBodyPut.java | 105 ++++++++++ .../model/system/SystemConfigurationRest.java | 194 ++++++++++++++++++ .../resource/SystemManagementResource.java | 4 +- .../hawkbit/rest/resource/SystemMapper.java | 87 ++++++++ .../hawkbit/rest/resource/SystemResource.java | 47 +++++ 11 files changed, 557 insertions(+), 3 deletions(-) create mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java create mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java rename hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/{TenantConfigurationRest.java => AuthenticationConfigurationRest.java} (96%) create mode 100644 hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java create mode 100644 hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java create mode 100644 hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java create mode 100644 hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.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 cdf91f879..9ba75835d 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 @@ -65,6 +65,19 @@ public enum SpServerError { */ SP_REST_SORT_PARAM_INVALID_DIRECTION("hawkbit.server.error.rest.param.invalidDirection", "The given sort parameter direction does not exist"), + + /** + * + */ + SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED("hawkbit.server.error.rest.param.invalidFormat", + "The given overdue polling time or polling time parameter are not formatted correctly."), + + /** + * + */ + SP_REST_CONFIG_INVALID_DS_TYPE("hawkbit.server.error.rest.param.invalidFormat", + "The given default distribution set type does not exist."), + /** * */ diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 09b6025d3..bade114d1 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository; import java.lang.reflect.Method; import java.math.BigDecimal; +import java.time.format.DateTimeParseException; import java.util.List; import java.util.stream.Collectors; @@ -20,10 +21,15 @@ import org.eclipse.hawkbit.cache.TenancyCacheManager; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetTypeException; +import org.eclipse.hawkbit.repository.exception.InvalidPollingTimeException; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantMetaData; +import org.eclipse.hawkbit.repository.model.helper.DurationHelper; +import org.eclipse.hawkbit.repository.specifications.DistributionSetTypeSpecification; +import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRequestBodyPut; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.persistence.config.PersistenceUnitProperties; @@ -461,4 +467,29 @@ public class SystemManagement implements EnvironmentAware { } + @Transactional + @Modifying + public void updateTenantConfiguration(SystemConfigurationRequestBodyPut systemConReq) { + + DurationHelper dh = new DurationHelper(); + + TenantMetaData tenantMetaData = getTenantMetadata(); + + String ddstypeKey = systemConReq.getDefaultDistributionSetType(); + + if (distributionSetTypeRepository.findAll(DistributionSetTypeSpecification.byKey(ddstypeKey)).isEmpty()) { + throw new InvalidDistributionSetTypeException( + String.format("The specified default distribution set type %s doe not exist.", ddstypeKey)); + } + + try { + tenantMetaData.setPollingOverdueTime(dh.formattedStringToDuration(systemConReq.getPollingOverdueTime())); + tenantMetaData.setPollingTime(dh.formattedStringToDuration(systemConReq.getPollingTime())); + } catch (DateTimeParseException ex) { + throw new InvalidPollingTimeException(ex); + } + + updateTenantMetadata(tenantMetaData); + } + } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java new file mode 100644 index 000000000..42fbe9c3c --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java @@ -0,0 +1,40 @@ +package org.eclipse.hawkbit.repository.exception; + +import org.eclipse.hawkbit.exception.SpServerError; +import org.eclipse.hawkbit.exception.SpServerRtException; + +/** + * This Exception is thrown, when the user wants to set a distribution set which + * does not exist, + * + */ +public class InvalidDistributionSetTypeException extends SpServerRtException { + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new CancelActionNotAllowed with + * {@link SpServerError#SP_ACTION_NOT_CANCELABLE} error. + */ + public InvalidDistributionSetTypeException() { + super(SpServerError.SP_REST_CONFIG_INVALID_DS_TYPE); + } + + /** + * @param cause + * for the exception + */ + public InvalidDistributionSetTypeException(final Throwable cause) { + super(SpServerError.SP_REST_CONFIG_INVALID_DS_TYPE, cause); + } + + /** + * @param message + * of the error + */ + public InvalidDistributionSetTypeException(final String message) { + super(message, SpServerError.SP_REST_CONFIG_INVALID_DS_TYPE); + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java new file mode 100644 index 000000000..818401563 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java @@ -0,0 +1,35 @@ +package org.eclipse.hawkbit.repository.exception; + +import org.eclipse.hawkbit.exception.SpServerError; +import org.eclipse.hawkbit.exception.SpServerRtException; + +public class InvalidPollingTimeException extends SpServerRtException { + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new CancelActionNotAllowed with + * {@link SpServerError#SP_ACTION_NOT_CANCELABLE} error. + */ + public InvalidPollingTimeException() { + super(SpServerError.SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED); + } + + /** + * @param cause + * for the exception + */ + public InvalidPollingTimeException(final Throwable cause) { + super(SpServerError.SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED, cause); + } + + /** + * @param message + * of the error + */ + public InvalidPollingTimeException(final String message) { + super(message, SpServerError.SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED); + } +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/RestConstants.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/RestConstants.java index 706584a64..bde96f7a8 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/RestConstants.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/RestConstants.java @@ -116,6 +116,8 @@ public final class RestConstants { * The target URL mapping rest resource. */ public static final String TARGET_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/targets"; + + public static final String SYSTEM_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/system"; /** * The software module URL mapping rest resource. */ diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/AuthenticationConfigurationRest.java similarity index 96% rename from hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java rename to hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/AuthenticationConfigurationRest.java index 2d31d9f61..1808bbc59 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/AuthenticationConfigurationRest.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public class TenantConfigurationRest { +public class AuthenticationConfigurationRest { private String key; private String value; diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java new file mode 100644 index 000000000..c5a3c219a --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java @@ -0,0 +1,105 @@ +package org.eclipse.hawkbit.rest.resource.model.system; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * A json annotated rest model for System Configuration for PUT. + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class SystemConfigurationRequestBodyPut { + + @JsonProperty + private String pollingTime; + + @JsonProperty + private String pollingOverdueTime; + + @JsonProperty + private String defaultDistributionSetType; + + @JsonProperty + private Map authenticationConfiguration; + + /** + * Gets the polling time. + * + * @return the polling time + */ + public String getPollingTime() { + return pollingTime; + } + + /** + * Sets the polling time. + * + * @param pollingTime + * the new polling time + */ + public void setPollingTime(String pollingTime) { + this.pollingTime = pollingTime; + } + + /** + * Gets the polling overdue time. + * + * @return the polling overdue time + */ + public String getPollingOverdueTime() { + return pollingOverdueTime; + } + + /** + * Sets the polling overdue time. + * + * @param pollingOverdueTime + * the new polling overdue time + */ + public void setPollingOverdueTime(String pollingOverdueTime) { + this.pollingOverdueTime = pollingOverdueTime; + } + + /** + * Gets the default distribution set type. + * + * @return the default distribution set type + */ + public String getDefaultDistributionSetType() { + return defaultDistributionSetType; + } + + /** + * Sets the default distribution set type. + * + * @param defaultDistributionSetType + * the new default distribution set type + */ + public void setDefaultDistributionSetType(String defaultDistributionSetType) { + this.defaultDistributionSetType = defaultDistributionSetType; + } + + /** + * Gets the authentication configuration. + * + * @return the authentication configuration + */ + public Map getAuthenticationConfiguration() { + return authenticationConfiguration; + } + + /** + * Sets the authentication configuration. + * + * @param authenticationConfiguration + * the authentication configuration + */ + public void setAuthenticationConfiguration(Map authenticationConfiguration) { + this.authenticationConfiguration = authenticationConfiguration; + } + +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java new file mode 100644 index 000000000..ee39027a3 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java @@ -0,0 +1,194 @@ +package org.eclipse.hawkbit.rest.resource.model.system; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * A json annotated rest model for SysteConfiguration to RESTful API + * representation. + * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class SystemConfigurationRest { + + @JsonProperty + private String pollingTime; + + @JsonProperty + private String pollingOverdueTime; + + @JsonProperty + private String defaultDistributionSetType; + + @JsonProperty + private String createdBy; + + @JsonProperty + private String lastModifiedBy; + + @JsonProperty + private Long createdAt; + + @JsonProperty + private Long lastModifiedAt; + + @JsonProperty + private Map authenticationConfiguration; + + /** + * Gets the polling time. + * + * @return the polling time + */ + public String getPollingTime() { + return pollingTime; + } + + /** + * Sets the polling time. + * + * @param pollingTime + * the new polling time + */ + public void setPollingTime(String pollingTime) { + this.pollingTime = pollingTime; + } + + /** + * Gets the polling overdue time. + * + * @return the polling overdue time + */ + public String getPollingOverdueTime() { + return pollingOverdueTime; + } + + /** + * Sets the polling overdue time. + * + * @param pollingOverdueTime + * the new polling overdue time + */ + public void setPollingOverdueTime(String pollingOverdueTime) { + this.pollingOverdueTime = pollingOverdueTime; + } + + /** + * Gets the default distribution set type. + * + * @return the default distribution set type + */ + public String getDefaultDistributionSetType() { + return defaultDistributionSetType; + } + + /** + * Sets the default distribution set type. + * + * @param defaultDistributionSetType + * the new default distribution set type + */ + public void setDefaultDistributionSetType(String defaultDistributionSetType) { + this.defaultDistributionSetType = defaultDistributionSetType; + } + + /** + * Gets the created by. + * + * @return the created by + */ + public String getCreatedBy() { + return createdBy; + } + + /** + * Sets the created by. + * + * @param createdBy + * the new created by + */ + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + /** + * Gets the last modified by. + * + * @return the last modified by + */ + public String getLastModifiedBy() { + return lastModifiedBy; + } + + /** + * Sets the last modified by. + * + * @param lastModifiedBy + * the new last modified by + */ + public void setLastModifiedBy(String lastModifiedBy) { + this.lastModifiedBy = lastModifiedBy; + } + + /** + * Gets the created at. + * + * @return the created at + */ + public Long getCreatedAt() { + return createdAt; + } + + /** + * Sets the created at. + * + * @param createdAt + * the new created at + */ + public void setCreatedAt(Long createdAt) { + this.createdAt = createdAt; + } + + /** + * Gets the last modified at. + * + * @return the last modified at + */ + public Long getLastModifiedAt() { + return lastModifiedAt; + } + + /** + * Sets the last modified at. + * + * @param lastModifiedAt + * the new last modified at + */ + public void setLastModifiedAt(Long lastModifiedAt) { + this.lastModifiedAt = lastModifiedAt; + } + + /** + * Sets the authentication configuration. + * + * @param authenticationConfiguration + * the authentication configuration + */ + public void setAuthenticationConfiguration(Map authenticationConfiguration) { + this.authenticationConfiguration = authenticationConfiguration; + } + + /** + * Gets the authentication configuration. + * + * @return the authentication configuration + */ + public Map getAuthenticationConfiguration() { + return this.authenticationConfiguration; + } +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java index 7213eae6d..6c4d86586 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java @@ -18,9 +18,9 @@ import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.report.model.TenantUsage; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.model.TenantConfiguration; +import org.eclipse.hawkbit.rest.resource.model.system.AuthenticationConfigurationRest; import org.eclipse.hawkbit.rest.resource.model.system.CacheRest; import org.eclipse.hawkbit.rest.resource.model.system.SystemStatisticsRest; -import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationRest; import org.eclipse.hawkbit.rest.resource.model.system.TenantSystemUsageRest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -141,7 +141,7 @@ public class SystemManagementResource { */ @RequestMapping(method = RequestMethod.PUT, value = "/conf/{key}") @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) - public ResponseEntity addUpdateConfig(@RequestBody final TenantConfigurationRest configuration, + public ResponseEntity addUpdateConfig(@RequestBody final AuthenticationConfigurationRest configuration, @PathVariable final String key) { systemManagement.addOrUpdateConfiguration(new TenantConfiguration(key, configuration.getValue())); return ResponseEntity.ok().build(); diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java new file mode 100644 index 000000000..47fa24b1b --- /dev/null +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java @@ -0,0 +1,87 @@ +package org.eclipse.hawkbit.rest.resource; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.model.TenantMetaData; +import org.eclipse.hawkbit.repository.model.helper.DurationHelper; +import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRest; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final public class SystemMapper { + + private static final Logger LOG = LoggerFactory.getLogger(SystemMapper.class); + + private SystemMapper() { + // Utility class + } + + private static DurationHelper dh = new DurationHelper(); + + public static SystemConfigurationRest toResponse(SystemManagement systemManagement) { + + TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + + SystemConfigurationRest sysconf = new SystemConfigurationRest(); + + sysconf.setDefaultDistributionSetType(tenantMetaData.getDefaultDsType().getKey()); + sysconf.setCreatedAt(tenantMetaData.getCreatedAt()); + sysconf.setCreatedBy(tenantMetaData.getCreatedBy()); + sysconf.setLastModifiedAt(tenantMetaData.getLastModifiedAt()); + sysconf.setLastModifiedBy(tenantMetaData.getLastModifiedBy()); + + sysconf.setPollingOverdueTime(dh.durationToFormattedString(tenantMetaData.getPollingOverdueTime())); + sysconf.setPollingTime(dh.durationToFormattedString(tenantMetaData.getPollingTime())); + + Map authconf = new HashMap(); + + for (TenantConfigurationKey key : TenantConfigurationKey.values()) { + Object value; + + switch (key) { + case AUTHENTICATION_MODE_HEADER_ENABLED: + case AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED: + case AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED: + value = systemManagement.getConfigurationValue(key, Boolean.class); + break; + case AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME: + case AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY: + case AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME: + value = systemManagement.getConfigurationValue(key, String.class); + break; + default: + LOG.warn("There is no data type specified for TenantConfigurationKey {}.", key.getKeyName()); + value = systemManagement.getConfigurationValue(key, String.class); + } + authconf.put(key.getKeyName(), value); + } + + sysconf.setAuthenticationConfiguration(authconf); + + return sysconf; + } + + public static TenantMetaData fromRequest(SystemManagement systemManagement, + SystemConfigurationRequestBodyPut systemConReq, DistributionSetManagement distributionSetManagement) { + + TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + + String ddstypeKey = systemConReq.getDefaultDistributionSetType(); + + if (distributionSetManagement.findDistributionSetTypeByKey(ddstypeKey) == null) { + throw new IllegalArgumentException( + String.format("The specified default distribution set type %s doe not exist.", ddstypeKey)); + } + + tenantMetaData.setPollingOverdueTime(dh.formattedStringToDuration(systemConReq.getPollingOverdueTime())); + tenantMetaData.setPollingTime(dh.formattedStringToDuration(systemConReq.getPollingTime())); + + return null; + + } +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java new file mode 100644 index 000000000..129261715 --- /dev/null +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java @@ -0,0 +1,47 @@ +package org.eclipse.hawkbit.rest.resource; + +import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(RestConstants.SYSTEM_V1_REQUEST_MAPPING) +public class SystemResource { + + private static final Logger LOGGER = LoggerFactory.getLogger(SystemResource.class); + + @Autowired + private SystemManagement systemManagement; + + @Autowired + private DistributionSetManagement distributionSetManagement; + + @RequestMapping(method = RequestMethod.GET, value = "/conf", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getSystemConfiguration() { + + return new ResponseEntity<>(SystemMapper.toResponse(systemManagement), HttpStatus.OK); + } + + @RequestMapping(method = RequestMethod.PUT, value = "/conf", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity updateSoftwareModuleType( + @RequestBody final SystemConfigurationRequestBodyPut systemConReq) { + + systemManagement.updateTenantConfiguration(systemConReq); + + return new ResponseEntity<>(SystemMapper.toResponse(systemManagement), HttpStatus.OK); + } + +} From f2e7cdb92ae2bf71332919ce44de574d45d4b73f Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 26 Jan 2016 13:56:42 +0100 Subject: [PATCH 11/42] Updated TenantConfigurationKey * added DataType of stored Value as attribute * added Polling keys to Enum Signed-off-by: Nonnenmacher Fabian --- .../configuration/TenantConfigurationKey.java | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index 477cd654e..45d6acf99 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -22,38 +22,53 @@ public enum TenantConfigurationKey { * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", - "hawkbit.server.controller.security.authentication.header.enabled", Boolean.FALSE.toString()), + "hawkbit.server.controller.security.authentication.header.enabled", Boolean.class, + Boolean.FALSE.toString()), /** * */ AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", - "hawkbit.server.controller.security.authentication.header.authority", Boolean.FALSE.toString()), + "hawkbit.server.controller.security.authentication.header.authority", Boolean.class, + Boolean.FALSE.toString()), /** * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", - "hawkbit.server.controller.security.authentication.targettoken.enabled", Boolean.FALSE.toString()), + "hawkbit.server.controller.security.authentication.targettoken.enabled", Boolean.class, + Boolean.FALSE.toString()), /** * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", - "hawkbit.server.controller.security.authentication.gatewaytoken.enabled", Boolean.FALSE.toString()), + "hawkbit.server.controller.security.authentication.gatewaytoken.enabled", Boolean.class, + Boolean.FALSE.toString()), /** * string value which holds the name of the security token key. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", - "hawkbit.server.controller.security.authentication.gatewaytoken.name", null), + "hawkbit.server.controller.security.authentication.gatewaytoken.name", String.class, null), /** * string value which holds the actual security-key of the gateway security * token. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", - "hawkbit.server.controller.security.authentication.gatewaytoken.key", null); + "hawkbit.server.controller.security.authentication.gatewaytoken.key", String.class, null), + + /** + * string value which holds the polling time interval in the format HH:mm:ss + */ + POLLING_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null), + + /** + * string value which holds the polling time interval in the format HH:mm:ss + */ + POLLING_OVERDUE_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null); private final String keyName; private final String defaultKeyName; + private final Class dataType; private final String defaultValue; /** @@ -62,10 +77,13 @@ public enum TenantConfigurationKey { * @param allowedValues * the allowed values for this specific key */ - private TenantConfigurationKey(final String key, final String defaultKeyName, final String defaultValue) { + private TenantConfigurationKey(final String key, final String defaultKeyName, final Class dataType, + final String defaultValue) { this.keyName = key; + this.dataType = dataType; this.defaultKeyName = defaultKeyName; this.defaultValue = defaultValue; + } /** @@ -88,4 +106,12 @@ public enum TenantConfigurationKey { public String getDefaultValue() { return defaultValue; } + + /** + * + * @return the datatype of the tenant configuration value + */ + public Class getDataType() { + return dataType; + } } From 07fce42469f44aa74a2061fb7ac798bfc02e23c0 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 26 Jan 2016 14:31:56 +0100 Subject: [PATCH 12/42] Changed return type of SystemManagement.getConfigurationValue() * changed Return type to wrapper object, adding additional meta data stored in the database * updated all calls of this method * updated function calls in tests * verified correct execution of correspending tests Signed-off-by: Nonnenmacher Fabian --- .../AmqpControllerAuthentficationTest.java | 26 ++- .../hawkbit/repository/SystemManagement.java | 82 ++++---- .../model/TenantConfigurationValue.java | 179 ++++++++++++++++++ .../repository/SystemManagementTest.java | 18 +- .../model/system/SystemConfigurationRest.java | 160 +--------------- .../hawkbit/rest/resource/SystemMapper.java | 57 +----- .../hawkbit/rest/resource/SystemResource.java | 2 +- ...bstractControllerAuthenticationFilter.java | 2 +- ...thenticatedGatewaySecurityTokenFilter.java | 2 +- ...rPreAuthenticatedSecurityHeaderFilter.java | 2 +- ...AuthenticationTenantConfigurationItem.java | 2 +- ...ficateAuthenticationConfigurationItem.java | 6 +- ...yTokenAuthenticationConfigurationItem.java | 4 +- ...yTokenAuthenticationConfigurationItem.java | 3 +- 14 files changed, 277 insertions(+), 268 deletions(-) create mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java index 1d962907b..8c4dc07c8 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java @@ -23,6 +23,7 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SecurityProperties; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; @@ -58,6 +59,12 @@ public class AmqpControllerAuthentficationTest { private SystemManagement systemManagement; private AmqpControllerAuthentfication authenticationManager; + private static final TenantConfigurationValue CONFIG_VALUE_FALSE = TenantConfigurationValue + . builder().value(Boolean.FALSE).build(); + + private static final TenantConfigurationValue CONFIG_VALUE_TRUE = TenantConfigurationValue + . builder().value(Boolean.TRUE).build(); + @Before public void before() throws Exception { amqpMessageHandlerService = new AmqpMessageHandlerService(); @@ -73,7 +80,8 @@ public class AmqpControllerAuthentficationTest { authenticationManager.setSecruityProperties(secruityProperties); systemManagement = mock(SystemManagement.class); authenticationManager.setSystemManagement(systemManagement); - when(systemManagement.getConfigurationValue(any(), any())).thenReturn(Boolean.FALSE); + + when(systemManagement.getConfigurationValue(any(), eq(Boolean.class))).thenReturn(CONFIG_VALUE_FALSE); final ControllerManagement controllerManagement = mock(ControllerManagement.class); when(controllerManagement.getSecurityTokenByControllerId(anyString())).thenReturn(CONTROLLLER_ID); @@ -104,8 +112,8 @@ public class AmqpControllerAuthentficationTest { public void testAuthenticationBadCredantialsWithWrongCredential() { final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); when(systemManagement.getConfigurationValue( - eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), any())) - .thenReturn(Boolean.TRUE); + eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) + .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID); try { authenticationManager.doAuthenticate(securityToken); @@ -121,8 +129,8 @@ public class AmqpControllerAuthentficationTest { public void testSuccessfullAuthentication() { final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); when(systemManagement.getConfigurationValue( - eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), any())) - .thenReturn(Boolean.TRUE); + eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) + .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID); final Authentication authentication = authenticationManager.doAuthenticate(securityToken); assertThat(authentication).isNotNull(); @@ -153,8 +161,8 @@ public class AmqpControllerAuthentficationTest { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); when(systemManagement.getConfigurationValue( - eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), any())) - .thenReturn(Boolean.TRUE); + eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) + .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); @@ -175,8 +183,8 @@ public class AmqpControllerAuthentficationTest { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); when(systemManagement.getConfigurationValue( - eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), any())) - .thenReturn(Boolean.TRUE); + eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) + .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index bade114d1..8cdc0f980 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository; import java.lang.reflect.Method; import java.math.BigDecimal; -import java.time.format.DateTimeParseException; import java.util.List; import java.util.stream.Collectors; @@ -21,15 +20,11 @@ import org.eclipse.hawkbit.cache.TenancyCacheManager; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetTypeException; -import org.eclipse.hawkbit.repository.exception.InvalidPollingTimeException; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.TenantConfiguration; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.repository.model.TenantMetaData; -import org.eclipse.hawkbit.repository.model.helper.DurationHelper; -import org.eclipse.hawkbit.repository.specifications.DistributionSetTypeSpecification; -import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRequestBodyPut; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.persistence.config.PersistenceUnitProperties; @@ -330,6 +325,8 @@ public class SystemManagement implements EnvironmentAware { * Retrieves a configuration value from the e.g. tenant overwritten * configuration values or in case the tenant does not a have a specific * configuration the global default value hold in the {@link Environment}. + * + * @param * * @param configurationKey * the key of the configuration @@ -345,15 +342,26 @@ public class SystemManagement implements EnvironmentAware { * {@code propertyType} */ @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") - public T getConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) { + public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, + final Class propertyType) { + final TenantConfiguration tenantConfiguration = tenantConfigurationRepository .findByKey(configurationKey.getKeyName()); + if (tenantConfiguration != null) { - return conversionService.convert(tenantConfiguration.getValue(), propertyType); + return TenantConfigurationValue. builder().isGlobal(false).createdBy(tenantConfiguration.getCreatedBy()) + .createdAt(tenantConfiguration.getCreatedAt()) + .lastModifiedAt(tenantConfiguration.getLastModifiedAt()) + .lastModifiedBy(tenantConfiguration.getLastModifiedBy()) + .value(conversionService.convert(tenantConfiguration.getValue(), propertyType)).build(); + } else if (configurationKey.getDefaultKeyName() != null) { - final T defaultKeyNameValue = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType); - return defaultKeyNameValue != null ? defaultKeyNameValue - : conversionService.convert(configurationKey.getDefaultValue(), propertyType); + final T valueInProperties = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType); + + return TenantConfigurationValue. builder().isGlobal(true).createdBy(null).createdAt(null) + .lastModifiedAt(null).lastModifiedBy(null).value(valueInProperties != null ? valueInProperties + : conversionService.convert(configurationKey.getDefaultValue(), propertyType)) + .build(); } return null; } @@ -467,29 +475,33 @@ public class SystemManagement implements EnvironmentAware { } - @Transactional - @Modifying - public void updateTenantConfiguration(SystemConfigurationRequestBodyPut systemConReq) { - - DurationHelper dh = new DurationHelper(); - - TenantMetaData tenantMetaData = getTenantMetadata(); - - String ddstypeKey = systemConReq.getDefaultDistributionSetType(); - - if (distributionSetTypeRepository.findAll(DistributionSetTypeSpecification.byKey(ddstypeKey)).isEmpty()) { - throw new InvalidDistributionSetTypeException( - String.format("The specified default distribution set type %s doe not exist.", ddstypeKey)); - } - - try { - tenantMetaData.setPollingOverdueTime(dh.formattedStringToDuration(systemConReq.getPollingOverdueTime())); - tenantMetaData.setPollingTime(dh.formattedStringToDuration(systemConReq.getPollingTime())); - } catch (DateTimeParseException ex) { - throw new InvalidPollingTimeException(ex); - } - - updateTenantMetadata(tenantMetaData); - } + // @Transactional + // @Modifying + // public void updateTenantConfiguration(SystemConfigurationRequestBodyPut + // systemConReq) { + // + // DurationHelper dh = new DurationHelper(); + // + // TenantMetaData tenantMetaData = getTenantMetadata(); + // + // String ddstypeKey = systemConReq.getDefaultDistributionSetType(); + // + // if + // (distributionSetTypeRepository.findAll(DistributionSetTypeSpecification.byKey(ddstypeKey)).isEmpty()) + // { + // throw new InvalidDistributionSetTypeException( + // String.format("The specified default distribution set type %s doe not + // exist.", ddstypeKey)); + // } + // + // try { + // tenantMetaData.setPollingOverdueTime(dh.formattedStringToDuration(systemConReq.getPollingOverdueTime())); + // tenantMetaData.setPollingTime(dh.formattedStringToDuration(systemConReq.getPollingTime())); + // } catch (DateTimeParseException ex) { + // throw new InvalidPollingTimeException(ex); + // } + // + // updateTenantMetadata(tenantMetaData); + // } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java new file mode 100644 index 000000000..140109596 --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java @@ -0,0 +1,179 @@ +package org.eclipse.hawkbit.repository.model; + +/** + * represents a tenant configuration value including some meta data + * + * @param + * type of the configuration value + */ +public class TenantConfigurationValue { + + private TenantConfigurationValue() { + } + + private T value = null; + private boolean isGlobal = true; + private Long lastModifiedAt = null; + private String lastModifiedBy = null; + private Long createdAt = null; + private String createdBy = null; + + /** + * Gets the value. + * + * @return the value + */ + public T getValue() { + return value; + } + + /** + * Checks if is global. + * + * @return true, if is global + */ + public boolean isGlobal() { + return isGlobal; + } + + /** + * Gets the last modified at. + * + * @return the last modified at + */ + public long getLastModifiedAt() { + return lastModifiedAt; + } + + /** + * Gets the last modified by. + * + * @return the last modified by + */ + public String getLastModifiedBy() { + return lastModifiedBy; + } + + /** + * Gets the created at. + * + * @return the created at + */ + public long getCreatedAt() { + return createdAt; + } + + /** + * Gets the created by. + * + * @return the created by + */ + public String getCreatedBy() { + return createdBy; + } + + /** + * Builder. + * + * @param + * the key type + * @return the tenant configuration value builder + */ + public static TenantConfigurationValueBuilder builder() { + + return new TenantConfigurationValueBuilder(); + } + + /** + * builds the tenant configuration value including some meta data + * + * @param + * type of the configuration value + */ + public static class TenantConfigurationValueBuilder { + + private final TenantConfigurationValue configuration = new TenantConfigurationValue<>(); + + /** + * Builds the. + * + * @return the tenant configuration value + */ + public TenantConfigurationValue build() { + return configuration; + } + + /** + * sets the configuration value itself + * + * @param value + * the value + * @return the tenant configuration value builder + */ + public TenantConfigurationValueBuilder value(final T value) { + this.configuration.value = value; + return this; + } + + /** + * set the is global attribute. + * + * @param isGlobal + * true when there is no tenant specific value, false + * otherwise + * @return the tenant configuration value builder + */ + public TenantConfigurationValueBuilder isGlobal(final boolean isGlobal) { + this.configuration.isGlobal = isGlobal; + return this; + } + + /** + * Sets the last modified at attribute + * + * @param lastModifiedAt + * timestamp of last modification + * @return the tenant configuration value builder + */ + public TenantConfigurationValueBuilder lastModifiedAt(final Long lastModifiedAt) { + this.configuration.lastModifiedAt = lastModifiedAt; + return this; + } + + /** + * sets the last modified by attribute + * + * @param lastModifiedBy + * the last modified by + * @return the tenant configuration value builder + */ + public TenantConfigurationValueBuilder lastModifiedBy(final String lastModifiedBy) { + this.configuration.lastModifiedBy = lastModifiedBy; + return this; + } + + /** + * sets the created at attribute + * + * @param createdAt + * defined when the configuration has been created + * @return the tenant configuration value builder + */ + public TenantConfigurationValueBuilder createdAt(final Long createdAt) { + this.configuration.createdAt = createdAt; + return this; + } + + /** + * sets the created by attribute + * + * @param createdBy + * defines by whom the configuration has been created + * @return the tenant configuration value builder + */ + public TenantConfigurationValueBuilder createdBy(final String createdBy) { + this.configuration.createdBy = createdBy; + return this; + } + } +} diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java index cdb76fd8d..a9461ff39 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java @@ -159,7 +159,7 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { assertThat(envPropertyDefault).isNotNull(); // get the configuration from the system management - final String defaultConfigValue = systemManagement.getConfigurationValue(configKey, String.class); + final String defaultConfigValue = systemManagement.getConfigurationValue(configKey, String.class).getValue(); assertThat(envPropertyDefault).isEqualTo(defaultConfigValue); // update the tenant specific configuration @@ -169,7 +169,8 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); // verify that new configuration value is used - final String updatedConfigurationValue = systemManagement.getConfigurationValue(configKey, String.class); + final String updatedConfigurationValue = systemManagement.getConfigurationValue(configKey, String.class) + .getValue(); assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); assertThat(systemManagement.getTenantConfigurations()).hasSize(1); } @@ -183,11 +184,11 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { // add value first systemManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value1)); - assertThat(systemManagement.getConfigurationValue(configKey, String.class)).isEqualTo(value1); + assertThat(systemManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value1); // update to value second systemManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value2)); - assertThat(systemManagement.getConfigurationValue(configKey, String.class)).isEqualTo(value2); + assertThat(systemManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value2); } @Test @@ -197,7 +198,7 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { final Integer value1 = 123; systemManagement .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), String.valueOf(value1))); - assertThat(systemManagement.getConfigurationValue(configKey, Integer.class)).isEqualTo(value1); + assertThat(systemManagement.getConfigurationValue(configKey, Integer.class).getValue()).isEqualTo(value1); } @Test(expected = ConversionFailedException.class) @@ -219,7 +220,7 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { // gateway token does not have default value so no configuration value // is should be available - final String defaultConfigValue = systemManagement.getConfigurationValue(configKey, String.class); + final String defaultConfigValue = systemManagement.getConfigurationValue(configKey, String.class).getValue(); assertThat(defaultConfigValue).isNull(); // update the tenant specific configuration @@ -229,13 +230,14 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); // verify that new configuration value is used - final String updatedConfigurationValue = systemManagement.getConfigurationValue(configKey, String.class); + final String updatedConfigurationValue = systemManagement.getConfigurationValue(configKey, String.class) + .getValue(); assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); // delete the tenant specific configuration systemManagement.deleteConfiguration(configKey); // ensure that now gateway token is set again, because is deleted and // must be null now - assertThat(systemManagement.getConfigurationValue(configKey, String.class)).isNull(); + assertThat(systemManagement.getConfigurationValue(configKey, String.class).getValue()).isNull(); } } diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java index ee39027a3..a73542afb 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java @@ -17,161 +17,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class SystemConfigurationRest { @JsonProperty - private String pollingTime; - - @JsonProperty - private String pollingOverdueTime; - - @JsonProperty - private String defaultDistributionSetType; - - @JsonProperty - private String createdBy; - - @JsonProperty - private String lastModifiedBy; - - @JsonProperty - private Long createdAt; - - @JsonProperty - private Long lastModifiedAt; - - @JsonProperty - private Map authenticationConfiguration; - - /** - * Gets the polling time. - * - * @return the polling time - */ - public String getPollingTime() { - return pollingTime; - } - - /** - * Sets the polling time. - * - * @param pollingTime - * the new polling time - */ - public void setPollingTime(String pollingTime) { - this.pollingTime = pollingTime; - } - - /** - * Gets the polling overdue time. - * - * @return the polling overdue time - */ - public String getPollingOverdueTime() { - return pollingOverdueTime; - } - - /** - * Sets the polling overdue time. - * - * @param pollingOverdueTime - * the new polling overdue time - */ - public void setPollingOverdueTime(String pollingOverdueTime) { - this.pollingOverdueTime = pollingOverdueTime; - } - - /** - * Gets the default distribution set type. - * - * @return the default distribution set type - */ - public String getDefaultDistributionSetType() { - return defaultDistributionSetType; - } - - /** - * Sets the default distribution set type. - * - * @param defaultDistributionSetType - * the new default distribution set type - */ - public void setDefaultDistributionSetType(String defaultDistributionSetType) { - this.defaultDistributionSetType = defaultDistributionSetType; - } - - /** - * Gets the created by. - * - * @return the created by - */ - public String getCreatedBy() { - return createdBy; - } - - /** - * Sets the created by. - * - * @param createdBy - * the new created by - */ - public void setCreatedBy(String createdBy) { - this.createdBy = createdBy; - } - - /** - * Gets the last modified by. - * - * @return the last modified by - */ - public String getLastModifiedBy() { - return lastModifiedBy; - } - - /** - * Sets the last modified by. - * - * @param lastModifiedBy - * the new last modified by - */ - public void setLastModifiedBy(String lastModifiedBy) { - this.lastModifiedBy = lastModifiedBy; - } - - /** - * Gets the created at. - * - * @return the created at - */ - public Long getCreatedAt() { - return createdAt; - } - - /** - * Sets the created at. - * - * @param createdAt - * the new created at - */ - public void setCreatedAt(Long createdAt) { - this.createdAt = createdAt; - } - - /** - * Gets the last modified at. - * - * @return the last modified at - */ - public Long getLastModifiedAt() { - return lastModifiedAt; - } - - /** - * Sets the last modified at. - * - * @param lastModifiedAt - * the new last modified at - */ - public void setLastModifiedAt(Long lastModifiedAt) { - this.lastModifiedAt = lastModifiedAt; - } + private Map configuration; /** * Sets the authentication configuration. @@ -180,7 +26,7 @@ public class SystemConfigurationRest { * the authentication configuration */ public void setAuthenticationConfiguration(Map authenticationConfiguration) { - this.authenticationConfiguration = authenticationConfiguration; + this.configuration = authenticationConfiguration; } /** @@ -189,6 +35,6 @@ public class SystemConfigurationRest { * @return the authentication configuration */ public Map getAuthenticationConfiguration() { - return this.authenticationConfiguration; + return this.configuration; } } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java index 47fa24b1b..a09f5fc73 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java @@ -3,7 +3,6 @@ package org.eclipse.hawkbit.rest.resource; import java.util.HashMap; import java.util.Map; -import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.repository.model.helper.DurationHelper; @@ -23,65 +22,25 @@ final public class SystemMapper { private static DurationHelper dh = new DurationHelper(); - public static SystemConfigurationRest toResponse(SystemManagement systemManagement) { + public static SystemConfigurationRest toResponse(final SystemManagement systemManagement) { - TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + final SystemConfigurationRest sysconf = new SystemConfigurationRest(); - SystemConfigurationRest sysconf = new SystemConfigurationRest(); + final Map authconf = new HashMap(); - sysconf.setDefaultDistributionSetType(tenantMetaData.getDefaultDsType().getKey()); - sysconf.setCreatedAt(tenantMetaData.getCreatedAt()); - sysconf.setCreatedBy(tenantMetaData.getCreatedBy()); - sysconf.setLastModifiedAt(tenantMetaData.getLastModifiedAt()); - sysconf.setLastModifiedBy(tenantMetaData.getLastModifiedBy()); - - sysconf.setPollingOverdueTime(dh.durationToFormattedString(tenantMetaData.getPollingOverdueTime())); - sysconf.setPollingTime(dh.durationToFormattedString(tenantMetaData.getPollingTime())); - - Map authconf = new HashMap(); - - for (TenantConfigurationKey key : TenantConfigurationKey.values()) { - Object value; - - switch (key) { - case AUTHENTICATION_MODE_HEADER_ENABLED: - case AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED: - case AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED: - value = systemManagement.getConfigurationValue(key, Boolean.class); - break; - case AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME: - case AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY: - case AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME: - value = systemManagement.getConfigurationValue(key, String.class); - break; - default: - LOG.warn("There is no data type specified for TenantConfigurationKey {}.", key.getKeyName()); - value = systemManagement.getConfigurationValue(key, String.class); - } + for (final TenantConfigurationKey key : TenantConfigurationKey.values()) { + final Object value = systemManagement.getConfigurationValue(key); authconf.put(key.getKeyName(), value); } - sysconf.setAuthenticationConfiguration(authconf); return sysconf; } - public static TenantMetaData fromRequest(SystemManagement systemManagement, - SystemConfigurationRequestBodyPut systemConReq, DistributionSetManagement distributionSetManagement) { - - TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); - - String ddstypeKey = systemConReq.getDefaultDistributionSetType(); - - if (distributionSetManagement.findDistributionSetTypeByKey(ddstypeKey) == null) { - throw new IllegalArgumentException( - String.format("The specified default distribution set type %s doe not exist.", ddstypeKey)); - } - - tenantMetaData.setPollingOverdueTime(dh.formattedStringToDuration(systemConReq.getPollingOverdueTime())); - tenantMetaData.setPollingTime(dh.formattedStringToDuration(systemConReq.getPollingTime())); + public static TenantMetaData fromRequest(final SystemManagement systemManagement, + final SystemConfigurationRequestBodyPut systemConReq) { + // TODO return null; - } } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java index 129261715..1b805cd43 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java @@ -39,7 +39,7 @@ public class SystemResource { public ResponseEntity updateSoftwareModuleType( @RequestBody final SystemConfigurationRequestBodyPut systemConReq) { - systemManagement.updateTenantConfiguration(systemConReq); + // systemManagement.updateTenantConfiguration(systemConReq); return new ResponseEntity<>(SystemMapper.toResponse(systemManagement), HttpStatus.OK); } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java index bbffc8748..e35ac890b 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java @@ -54,7 +54,7 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe @Override public Boolean run() { LOGGER.trace("retrieving configuration value for configuration key {}", getTenantConfigurationKey()); - return systemManagement.getConfigurationValue(getTenantConfigurationKey(), Boolean.class); + return systemManagement.getConfigurationValue(getTenantConfigurationKey(), Boolean.class).getValue(); } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java index 7e8848ed8..1e890e33d 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -85,7 +85,7 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra LOGGER.trace("retrieving configuration value for configuration key {}", TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY); return systemManagement.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class); + TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue(); } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java index 066efca53..369b618e7 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java @@ -143,7 +143,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont @Override public String run() { return systemManagement.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class); + TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class).getValue(); } } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java index aae5c592d..f71adaaf2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java @@ -66,7 +66,7 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay */ @Override public boolean isConfigEnabled() { - boolean b = systemManagement.getConfigurationValue(configurationKey, Boolean.class); + final boolean b = systemManagement.getConfigurationValue(configurationKey, Boolean.class).getValue(); return b; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java index 331fc976e..b4210b6fb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java @@ -153,13 +153,15 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti configurationEnabledChange = false; configurationCaRootAuthorityChanged = false; - configurationEnabled = getSystemManagement().getConfigurationValue(getConfigurationKey(), Boolean.class); + configurationEnabled = getSystemManagement().getConfigurationValue(getConfigurationKey(), Boolean.class) + .getValue(); caRootAuthorityTextField.setValue(getCaRootAuthorityValue()); } private String getCaRootAuthorityValue() { return getSystemManagement() - .getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class); + .getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class) + .getValue(); } private void setDetailVisible(final boolean visible) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java index 6ae002263..c9fb175b8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java @@ -168,12 +168,12 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac private String getSecurityTokenName() { return getSystemManagement().getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME, String.class); + TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME, String.class).getValue(); } private String getSecurityTokenKey() { return getSystemManagement().getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class); + TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue(); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java index 683e1cd69..768ee1d92 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java @@ -96,6 +96,7 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract @Override public void undo() { configurationEnabledChange = false; - configurationEnabled = getSystemManagement().getConfigurationValue(getConfigurationKey(), Boolean.class); + configurationEnabled = getSystemManagement().getConfigurationValue(getConfigurationKey(), Boolean.class) + .getValue(); } } From 3f2c0d134a546af97e1e107c4dc5047ff5bb1857 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 26 Jan 2016 16:24:07 +0100 Subject: [PATCH 13/42] Updated UI to use new database structure * use new methods to store polling Configuration * refactored DurationConfigField, added Builder Signed-off-by: Nonnenmacher Fabian --- .../model/helper/DurationHelper.java | 8 +- .../PollingConfigurationView.java | 102 +++++++------- .../polling/DurationConfigField.java | 129 +++++++++--------- 3 files changed, 126 insertions(+), 113 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java index d14752f8f..bedda71a6 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java @@ -15,7 +15,7 @@ import java.time.temporal.TemporalAccessor; public class DurationHelper { /** - * Format of the String expected in configuration file and in the databse. + * Format of the String expected in configuration file and in the database. */ public static final String DURATION_FORMAT = "HH:mm:ss"; @@ -27,7 +27,7 @@ public class DurationHelper { * @return String in the duration format, specified at * {@link #DURATION_FORMAT} */ - public String durationToFormattedString(Duration duration) { + public String durationToFormattedString(final Duration duration) { if (duration == null) { return null; } @@ -44,7 +44,7 @@ public class DurationHelper { * @throws DateTimeParseException * when String is in wrong format */ - public Duration formattedStringToDuration(String formattedDuration) throws DateTimeParseException { + public Duration formattedStringToDuration(final String formattedDuration) throws DateTimeParseException { if (formattedDuration == null) { return null; } @@ -64,7 +64,7 @@ public class DurationHelper { * count of seconds * @return duration */ - public Duration getDurationByTimeValues(long hours, long minutes, long seconds) { + public Duration getDurationByTimeValues(final long hours, final long minutes, final long seconds) { return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 537e839ba..80865410c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -4,9 +4,12 @@ import java.time.Duration; import javax.annotation.PostConstruct; +import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.repository.SystemManagement; -import org.eclipse.hawkbit.repository.model.TenantMetaData; -import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; +import org.eclipse.hawkbit.repository.model.TenantConfiguration; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; +import org.eclipse.hawkbit.repository.model.helper.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.tenantconfiguration.polling.DurationConfigField; import org.eclipse.hawkbit.ui.utils.I18N; import org.springframework.beans.factory.annotation.Autowired; @@ -34,19 +37,23 @@ public class PollingConfigurationView extends BaseConfigurationView private I18N i18n; @Autowired - PollConfigurationHelper pollConfigurationHelper; + private ControllerPollProperties controllerPollProperties; @Autowired private transient SystemManagement systemManagement; - @Autowired - private DurationConfigField fieldPollingTime; + private DurationConfigField fieldPollTime = null; + private DurationConfigField fieldPollingOverdueTime = null; - @Autowired - private DurationConfigField fieldPollingOverdueTime; + private Duration minDuration; + private Duration maxDuration; + private Duration globalPollTime; + private Duration globalOverdueTime; - private Duration tenantPollingTime; - private Duration tenantPollingOverdueTime; + private Duration tenantPollTime = null; + private Duration tenantOverdueTime = null; + + private final DurationHelper durationHelper = new DurationHelper(); /** * Initialize Authentication Configuration layout. @@ -54,37 +61,44 @@ public class PollingConfigurationView extends BaseConfigurationView @PostConstruct public void init() { + minDuration = durationHelper.formattedStringToDuration(controllerPollProperties.getMinPollingTime()); + maxDuration = durationHelper.formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); + globalPollTime = durationHelper.formattedStringToDuration(controllerPollProperties.getPollingTime()); + globalOverdueTime = durationHelper.formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); + + final TenantConfigurationValue pollTimeConfValue = systemManagement + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class); + if (!pollTimeConfValue.isGlobal()) { + tenantPollTime = durationHelper.formattedStringToDuration(pollTimeConfValue.getValue()); + } + + final TenantConfigurationValue overdueTimeConfValue = systemManagement + .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class); + if (!overdueTimeConfValue.isGlobal()) { + tenantOverdueTime = durationHelper.formattedStringToDuration(overdueTimeConfValue.getValue()); + } + final Panel rootPanel = new Panel(); rootPanel.setSizeFull(); rootPanel.addStyleName("config-panel"); final VerticalLayout vLayout = new VerticalLayout(); vLayout.setMargin(true); - // vLayout.setSizeFull(); final Label headerDisSetType = new Label(i18n.get("configuration.polling.title")); headerDisSetType.addStyleName("config-panel-header"); vLayout.addComponent(headerDisSetType); - final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); + fieldPollTime = DurationConfigField.builder().caption(i18n.get("configuration.polling.time")) + .checkBoxLabel(i18n.get("configuration.polling.custom.value")).range(minDuration, maxDuration) + .globalDuration(globalPollTime).tenantDuration(tenantPollTime).build(); + fieldPollTime.addChangeListener(this); + vLayout.addComponent(fieldPollTime); - tenantPollingTime = tenantMetaData.getPollingTime(); - fieldPollingTime.setInitValues(i18n.get("configuration.polling.time"), tenantPollingTime, - pollConfigurationHelper.getGlobalPollTimeInterval()); - fieldPollingTime.setAllowedRange(pollConfigurationHelper.getMinimumPollingInterval(), - pollConfigurationHelper.getMaximumPollingInterval()); - fieldPollingTime.addChangeListener(this); - - vLayout.addComponent(fieldPollingTime); - - tenantPollingOverdueTime = tenantMetaData.getPollingOverdueTime(); - - fieldPollingOverdueTime.setInitValues(i18n.get("configuration.polling.overduetime"), tenantPollingOverdueTime, - pollConfigurationHelper.getGlobalOverduePollTimeInterval()); - fieldPollingOverdueTime.setAllowedRange(pollConfigurationHelper.getMinimumPollingInterval(), - pollConfigurationHelper.getMaximumPollingInterval()); + fieldPollingOverdueTime = DurationConfigField.builder().caption(i18n.get("configuration.polling.overduetime")) + .checkBoxLabel(i18n.get("configuration.polling.custom.value")).range(minDuration, maxDuration) + .globalDuration(globalPollTime).tenantDuration(tenantOverdueTime).build(); fieldPollingOverdueTime.addChangeListener(this); - vLayout.addComponent(fieldPollingOverdueTime); rootPanel.setContent(vLayout); @@ -95,36 +109,30 @@ public class PollingConfigurationView extends BaseConfigurationView public void save() { // make sure values are only saved, when the value has been changed - boolean hasChanged = false; - - final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata(); - - if (!compareDurations(tenantPollingTime, fieldPollingTime.getValue())) { - tenantPollingTime = fieldPollingTime.getValue(); - tenantMetaData.setPollingTime(fieldPollingTime.getValue()); - hasChanged = true; + if (!compareDurations(tenantPollTime, fieldPollTime.getValue())) { + tenantPollTime = fieldPollTime.getValue(); + systemManagement.addOrUpdateConfiguration( + new TenantConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL.getKeyName(), + durationHelper.durationToFormattedString(tenantPollTime))); } - if (!compareDurations(tenantPollingOverdueTime, fieldPollingOverdueTime.getValue())) { - tenantPollingOverdueTime = fieldPollingOverdueTime.getValue(); - tenantMetaData.setPollingOverdueTime(fieldPollingOverdueTime.getValue()); - hasChanged = true; - } - - if (hasChanged) { - systemManagement.updateTenantMetadata(tenantMetaData); + if (!compareDurations(tenantOverdueTime, fieldPollingOverdueTime.getValue())) { + tenantOverdueTime = fieldPollingOverdueTime.getValue(); + systemManagement.addOrUpdateConfiguration( + new TenantConfiguration(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL.getKeyName(), + durationHelper.durationToFormattedString(tenantOverdueTime))); } } @Override public void undo() { - fieldPollingTime.setValue(tenantPollingTime); - fieldPollingOverdueTime.setValue(tenantPollingOverdueTime); + fieldPollTime.setValue(tenantPollTime); + fieldPollingOverdueTime.setValue(tenantOverdueTime); } @Override public boolean isUserInputValid() { - return fieldPollingTime.isUserInputValid() && fieldPollingOverdueTime.isUserInputValid(); + return fieldPollTime.isUserInputValid() && fieldPollingOverdueTime.isUserInputValid(); } @Override @@ -132,7 +140,7 @@ public class PollingConfigurationView extends BaseConfigurationView notifyConfigurationChanged(); } - private boolean compareDurations(Duration d1, Duration d2) { + private boolean compareDurations(final Duration d1, final Duration d2) { if (d1 == null && d2 == null) { return true; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index a16accbae..c311489e0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -4,20 +4,12 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; -import javax.annotation.PostConstruct; -import javax.validation.constraints.NotNull; - import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationItem; -import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; -import com.vaadin.spring.annotation.SpringComponent; -import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.Alignment; import com.vaadin.ui.CheckBox; import com.vaadin.ui.GridLayout; @@ -29,68 +21,41 @@ import com.vaadin.ui.Label; * duration in the DurationField or he can configure using the global duration * by changing the CheckBox. */ -@SpringComponent -@ViewScope -@Scope("prototype") public class DurationConfigField extends GridLayout implements ValueChangeListener, ConfigurationItem { private static final long serialVersionUID = 1L; private final List configurationChangeListeners = new ArrayList<>(); - private CheckBox checkBox; - private DurationField durationField; - + private final CheckBox checkBox = new CheckBox(); + private final DurationField durationField = new DurationField(); private Duration globalDuration; + private final Label labelCustomValue; - @Autowired - private I18N i18n; - - /** - * sets i18n - * - * @param i18n - */ - public void setI18n(I18N i18n) { - this.i18n = i18n; - } - - public DurationConfigField() { + private DurationConfigField() { super(3, 2); - } - - /** - * Initialize Authentication Configuration layout. - */ - @PostConstruct - public void init() { this.addStyleName("duration-config-field"); this.setSpacing(true); this.setImmediate(true); this.setColumnExpandRatio(1, 1.0F); - // gridLayout.setSizeFull(); - - checkBox = new CheckBox(); this.addComponent(checkBox, 0, 0); this.setComponentAlignment(checkBox, Alignment.MIDDLE_LEFT); - Label customValue = SPUIComponentProvider.getLabel(i18n.get("configuration.polling.custom.value"), - SPUILabelDefinitions.SP_LABEL_SIMPLE); - this.addComponent(customValue, 1, 0); - this.setComponentAlignment(customValue, Alignment.MIDDLE_LEFT); - - durationField = new DurationField(); + labelCustomValue = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); + this.addComponent(labelCustomValue, 1, 0); + this.setComponentAlignment(labelCustomValue, Alignment.MIDDLE_LEFT); this.addComponent(durationField, 2, 0); this.setComponentAlignment(durationField, Alignment.MIDDLE_LEFT); checkBox.addValueChangeListener(this); + durationField.addValueChangeListener(this); } @Override - public void valueChange(ValueChangeEvent event) { + public void valueChange(final ValueChangeEvent event) { if (event.getProperty() == checkBox) { if (checkBox.getValue()) { durationField.setEnabled(true); @@ -103,35 +68,25 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen } /** - * sets all mandatitory attributes for correct user interaction - * - * @param caption - * the caption of the field + * has to be called before using, see Builder Implementation. * * @param tenantDuration * tenant specific duration value * @param globalDuration * duration value which is stored in the global configuration */ - public void setInitValues(String caption, @NotNull Duration tenantDuration, @NotNull Duration globalDuration) { - this.setCaption(caption); + private void init(final Duration globalDuration, final Duration tenantDuration) { this.globalDuration = globalDuration; - this.setValue(tenantDuration); } - /** - * sets the allowed range of the duration values - * - * @param minimumDuration - * minimum allowed duration value - * @param maximumDuration - * maximum allowed duration value - */ - public void setAllowedRange(Duration minimumDuration, Duration maximumDuration) { + private void setCheckboxLabel(final String label) { + labelCustomValue.setValue(label); + } + + private void setAllowedRange(final Duration minimumDuration, final Duration maximumDuration) { durationField.setMinimumDuration(minimumDuration); durationField.setMaximumDuration(maximumDuration); - } /** @@ -141,7 +96,7 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen * duration which will be set in to the duration field, when * {@code null} the global configuration will be used. */ - public void setValue(Duration tenantDuration) { + public void setValue(final Duration tenantDuration) { if (tenantDuration == null) { // no tenant specific configuration checkBox.setValue(false); @@ -178,4 +133,54 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen public void addChangeListener(final ConfigurationItemChangeListener listener) { configurationChangeListeners.add(listener); } + + public static DurationConfigFieldBuilder builder() { + return new DurationConfigFieldBuilder(); + } + + public static class DurationConfigFieldBuilder { + private final DurationConfigField field; + + private Duration globalDuration = null; + private Duration tenantDuration = null; + + private DurationConfigFieldBuilder() { + field = new DurationConfigField(); + }; + + public DurationConfigFieldBuilder checkBoxLabel(final String label) { + field.setCheckboxLabel(label); + return this; + } + + public DurationConfigFieldBuilder globalDuration(final Duration globalDuration) { + this.globalDuration = globalDuration; + return this; + } + + public DurationConfigFieldBuilder caption(final String caption) { + field.setCaption(caption); + return this; + } + + public DurationConfigFieldBuilder range(final Duration minDuration, final Duration maxDuration) { + field.setAllowedRange(minDuration, maxDuration); + return this; + } + + public DurationConfigFieldBuilder tenantDuration(final Duration tenantDuration) { + this.tenantDuration = tenantDuration; + return this; + } + + public DurationConfigField build() { + if (globalDuration == null) { + throw new IllegalStateException( + "Cannot build DurationConfigField without a value for global duration."); + } + + field.init(globalDuration, tenantDuration); + return field; + } + }; } From b56477191a80df13d74f10b1f7b30a7bd9082e48 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Wed, 27 Jan 2016 16:19:42 +0100 Subject: [PATCH 14/42] Added generic validator fucntion to TenantConfigurationKey Signed-off-by: Nonnenmacher Fabian --- .../configuration}/DurationHelper.java | 22 ++++++++- .../configuration/TenantConfigurationKey.java | 40 ++++++++++++---- .../validator/BooleanValidator.java | 13 +++++ .../validator/PollTimeValidator.java | 47 +++++++++++++++++++ .../validator/StringValidator.java | 13 +++++ .../TenantConfigurationValidator.java | 6 +++ ...Rest.java => TenantConfigurationRest.java} | 2 +- 7 files changed, 130 insertions(+), 13 deletions(-) rename {hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper => hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration}/DurationHelper.java (76%) create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java rename hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/{AuthenticationConfigurationRest.java => TenantConfigurationRest.java} (96%) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java similarity index 76% rename from hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java rename to hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java index bedda71a6..79f5305c5 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/DurationHelper.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java @@ -1,4 +1,4 @@ -package org.eclipse.hawkbit.repository.model.helper; +package org.eclipse.hawkbit.tenancy.configuration; import java.time.Duration; import java.time.LocalTime; @@ -36,7 +36,7 @@ public class DurationHelper { } /** - * Converts a formatted Sting into a Duration object. + * Converts a formatted String into a Duration object. * * @param formattedDuration * String in {@link #DURATION_FORMAT} @@ -67,4 +67,22 @@ public class DurationHelper { public Duration getDurationByTimeValues(final long hours, final long minutes, final long seconds) { return Duration.ofHours(hours).plusMinutes(minutes).plusSeconds(seconds); } + + public DurationRangeValidator durationRangeValidator(final Duration min, final Duration max) { + return new DurationRangeValidator(min, max); + } + + public static class DurationRangeValidator { + final Duration min; + final Duration max; + + private DurationRangeValidator(final Duration min, final Duration max) { + this.min = min; + this.max = max; + } + + public boolean isWithinRange(final Duration duration) { + return duration.compareTo(min) > 0 && duration.compareTo(max) < 0; + } + } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index 45d6acf99..701038cb1 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -8,6 +8,12 @@ */ package org.eclipse.hawkbit.tenancy.configuration; +import org.eclipse.hawkbit.tenancy.configuration.validator.BooleanValidator; +import org.eclipse.hawkbit.tenancy.configuration.validator.PollTimeValidator; +import org.eclipse.hawkbit.tenancy.configuration.validator.StringValidator; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidator; +import org.springframework.context.ApplicationContext; + /** * An enum which defines the tenant specific configurations which can be * configured for each tenant seperately. @@ -22,54 +28,59 @@ public enum TenantConfigurationKey { * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", - "hawkbit.server.controller.security.authentication.header.enabled", Boolean.class, - Boolean.FALSE.toString()), + "hawkbit.server.controller.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(), + BooleanValidator.class), /** * */ AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", "hawkbit.server.controller.security.authentication.header.authority", Boolean.class, - Boolean.FALSE.toString()), + Boolean.FALSE.toString(), BooleanValidator.class), /** * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", "hawkbit.server.controller.security.authentication.targettoken.enabled", Boolean.class, - Boolean.FALSE.toString()), + Boolean.FALSE.toString(), BooleanValidator.class), /** * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", "hawkbit.server.controller.security.authentication.gatewaytoken.enabled", Boolean.class, - Boolean.FALSE.toString()), + Boolean.FALSE.toString(), BooleanValidator.class), /** * string value which holds the name of the security token key. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", - "hawkbit.server.controller.security.authentication.gatewaytoken.name", String.class, null), + "hawkbit.server.controller.security.authentication.gatewaytoken.name", String.class, null, + StringValidator.class), /** * string value which holds the actual security-key of the gateway security * token. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", - "hawkbit.server.controller.security.authentication.gatewaytoken.key", String.class, null), + "hawkbit.server.controller.security.authentication.gatewaytoken.key", String.class, null, + StringValidator.class), /** * string value which holds the polling time interval in the format HH:mm:ss */ - POLLING_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null), + POLLING_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null, + PollTimeValidator.class), /** * string value which holds the polling time interval in the format HH:mm:ss */ - POLLING_OVERDUE_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null); + POLLING_OVERDUE_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null, + PollTimeValidator.class); private final String keyName; private final String defaultKeyName; private final Class dataType; private final String defaultValue; + private final Class validator; /** * @param key @@ -78,11 +89,12 @@ public enum TenantConfigurationKey { * the allowed values for this specific key */ private TenantConfigurationKey(final String key, final String defaultKeyName, final Class dataType, - final String defaultValue) { + final String defaultValue, final Class validator) { this.keyName = key; this.dataType = dataType; this.defaultKeyName = defaultKeyName; this.defaultValue = defaultValue; + this.validator = validator; } @@ -114,4 +126,12 @@ public enum TenantConfigurationKey { public Class getDataType() { return dataType; } + + public boolean validate(final ApplicationContext context, final Object value) { + final TenantConfigurationValidator createBean = context.getAutowireCapableBeanFactory().createBean(validator); + final boolean isValid = createBean.validate(value); + context.getAutowireCapableBeanFactory().destroyBean(createBean); + return isValid; + } + } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java new file mode 100644 index 000000000..208e3d01c --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java @@ -0,0 +1,13 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator; + +public class BooleanValidator implements TenantConfigurationValidator { + + @Override + public boolean validate(final Object tenantConfigurationValue) { + if (tenantConfigurationValue instanceof Boolean) { + return true; + } + return false; + } + +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java new file mode 100644 index 000000000..b2a2ec00b --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java @@ -0,0 +1,47 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator; + +import java.time.Duration; +import java.time.format.DateTimeParseException; + +import org.eclipse.hawkbit.ControllerPollProperties; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.springframework.beans.factory.annotation.Autowired; + +public class PollTimeValidator implements TenantConfigurationValidator { + + // private final ControllerPollProperties properties; + + private final DurationHelper durationHelper = new DurationHelper(); + + private final Duration minDuration; + + private final Duration maxDuration; + + @Autowired + public PollTimeValidator(final ControllerPollProperties properties) { + // this.properties = properties; + + minDuration = durationHelper.formattedStringToDuration(properties.getMinPollingTime()); + maxDuration = durationHelper.formattedStringToDuration(properties.getMaxPollingTime()); + } + + @Override + public boolean validate(final Object tenantConfigurationObject) { + if (!(tenantConfigurationObject instanceof String)) { + return false; + } + + final String tenantConfigurationString = (String) tenantConfigurationObject; + + try { + final Duration tenantConfigurationValue = durationHelper + .formattedStringToDuration(tenantConfigurationString); + + return durationHelper.durationRangeValidator(minDuration, maxDuration) + .isWithinRange(tenantConfigurationValue); + + } catch (final DateTimeParseException ex) { + return false; + } + } +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java new file mode 100644 index 000000000..925d46cb9 --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java @@ -0,0 +1,13 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator; + +public class StringValidator implements TenantConfigurationValidator { + + @Override + public boolean validate(final Object tenantConfigurationValue) { + if (tenantConfigurationValue instanceof String) { + return true; + } + + return false; + } +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java new file mode 100644 index 000000000..3d2f0b1c7 --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java @@ -0,0 +1,6 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator; + +public interface TenantConfigurationValidator { + + boolean validate(Object tenantConfigurationValue); +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/AuthenticationConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java similarity index 96% rename from hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/AuthenticationConfigurationRest.java rename to hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java index 1808bbc59..2d31d9f61 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/AuthenticationConfigurationRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java @@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public class AuthenticationConfigurationRest { +public class TenantConfigurationRest { private String key; private String value; From 6cef6aed1a9347c38850ff3c2fadf23d99678d29 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Wed, 27 Jan 2016 17:00:39 +0100 Subject: [PATCH 15/42] Moved tenant configuration functions to new management class - moved fucntions to TenantConfigurationManagement, for better function capseling - updated references - updated references in tests, tests were succesfully Signed-off-by: Nonnenmacher Fabian --- .../SecurityManagedConfiguration.java | 9 +- .../amqp/AmqpControllerAuthentfication.java | 16 +- .../AmqpControllerAuthentficationTest.java | 18 +-- ...actHttpControllerAuthenticationFilter.java | 8 +- ...lerPreAuthenticateSecurityTokenFilter.java | 12 +- ...thenticatedGatewaySecurityTokenFilter.java | 10 +- ...rPreAuthenticatedSecurityHeaderFilter.java | 8 +- .../RepositoryApplicationConfiguration.java | 23 +-- .../hawkbit/repository/SystemManagement.java | 140 +----------------- .../TenantConfigurationManagement.java | 125 ++++++++++++++++ .../hawkbit/repository/model/TargetInfo.java | 16 +- .../model/TenantConfigurationValue.java | 4 +- .../hawkbit/AbstractIntegrationTest.java | 5 + .../repository/SystemManagementTest.java | 92 ------------ .../TenantConfigurationManagementTest.java | 113 ++++++++++++++ .../model/system/SystemConfigurationRest.java | 10 +- .../system/TenantConfigurationValueRest.java | 60 ++++++++ .../resource/SystemManagementResource.java | 10 +- .../hawkbit/rest/resource/SystemMapper.java | 32 ++-- .../hawkbit/rest/resource/SystemResource.java | 9 +- ...bstractControllerAuthenticationFilter.java | 11 +- ...lerPreAuthenticateSecurityTokenFilter.java | 7 +- ...thenticatedGatewaySecurityTokenFilter.java | 10 +- ...rPreAuthenticatedSecurityHeaderFilter.java | 8 +- .../PollingConfigurationView.java | 16 +- ...AuthenticationTenantConfigurationItem.java | 20 +-- ...ficateAuthenticationConfigurationItem.java | 17 ++- ...yTokenAuthenticationConfigurationItem.java | 17 ++- ...yTokenAuthenticationConfigurationItem.java | 13 +- 29 files changed, 466 insertions(+), 373 deletions(-) create mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java create mode 100644 hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java create mode 100644 hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java 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 ca55f1711..c7301efd1 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 @@ -29,6 +29,7 @@ import org.eclipse.hawkbit.im.authentication.TenantUserPasswordAuthenticationTok import org.eclipse.hawkbit.im.authentication.UserAuthenticationFilter; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.rest.resource.RestConstants; import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSource; import org.eclipse.hawkbit.security.DosFilter; @@ -119,7 +120,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware { @Autowired private ControllerManagement controllerManagement; @Autowired - private SystemManagement systemManagement; + private TenantConfigurationManagement tenantConfigurationManagement; @Autowired private TenantAware tenantAware; @Autowired @@ -133,19 +134,19 @@ public class SecurityManagedConfiguration implements EnvironmentAware { final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter( securityConfiguration.getRpCnHeader(), securityConfiguration.getRpSslIssuerHashHeader(), - systemManagement, tenantAware); + tenantConfigurationManagement, tenantAware); securityHeaderFilter.setAuthenticationManager(authenticationManager()); securityHeaderFilter.setCheckForPrincipalChanges(true); securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource); final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter( - systemManagement, tenantAware, controllerManagement); + tenantConfigurationManagement, tenantAware, controllerManagement); securityTokenFilter.setAuthenticationManager(authenticationManager()); securityTokenFilter.setCheckForPrincipalChanges(true); securityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource); final HttpControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new HttpControllerPreAuthenticatedGatewaySecurityTokenFilter( - systemManagement, tenantAware); + tenantConfigurationManagement, tenantAware); gatewaySecurityTokenFilter.setAuthenticationManager(authenticationManager()); gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true); gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource); diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java index dd36ef1fd..f19907a99 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java @@ -16,7 +16,7 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.repository.ControllerManagement; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter; @@ -49,7 +49,7 @@ public class AmqpControllerAuthentfication { private ControllerManagement controllerManagement; @Autowired - private SystemManagement systemManagement; + private TenantConfigurationManagement tenantConfigurationManagement; @Autowired private TenantAware tenantAware; @@ -74,16 +74,16 @@ public class AmqpControllerAuthentfication { private void addFilter() { final ControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new ControllerPreAuthenticatedGatewaySecurityTokenFilter( - systemManagement, tenantAware); + tenantConfigurationManagement, tenantAware); filterChain.add(gatewaySecurityTokenFilter); final ControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new ControllerPreAuthenticatedSecurityHeaderFilter( - secruityProperties.getRpCnHeader(), secruityProperties.getRpSslIssuerHashHeader(), systemManagement, - tenantAware); + secruityProperties.getRpCnHeader(), secruityProperties.getRpSslIssuerHashHeader(), + tenantConfigurationManagement, tenantAware); filterChain.add(securityHeaderFilter); final ControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new ControllerPreAuthenticateSecurityTokenFilter( - systemManagement, controllerManagement, tenantAware); + tenantConfigurationManagement, controllerManagement, tenantAware); filterChain.add(securityTokenFilter); filterChain.add(new CoapAnonymousPreAuthenticatedFilter()); @@ -141,8 +141,8 @@ public class AmqpControllerAuthentfication { this.secruityProperties = secruityProperties; } - public void setSystemManagement(final SystemManagement systemManagement) { - this.systemManagement = systemManagement; + public void setTenantConfigurationManagement(final TenantConfigurationManagement tenantConfigurationManagement) { + this.tenantConfigurationManagement = tenantConfigurationManagement; } public void setTenantAware(final TenantAware tenantAware) { diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java index 8c4dc07c8..e25afe490 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java @@ -22,7 +22,7 @@ import org.eclipse.hawkbit.dmf.json.model.DownloadResponse; import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SecurityProperties; @@ -56,7 +56,7 @@ public class AmqpControllerAuthentficationTest { private static String CONTROLLLER_ID = "123"; private AmqpMessageHandlerService amqpMessageHandlerService; private MessageConverter messageConverter; - private SystemManagement systemManagement; + private TenantConfigurationManagement tenantConfigurationManagement; private AmqpControllerAuthentfication authenticationManager; private static final TenantConfigurationValue CONFIG_VALUE_FALSE = TenantConfigurationValue @@ -78,10 +78,10 @@ public class AmqpControllerAuthentficationTest { final SecurityProperties secruityProperties = mock(SecurityProperties.class); when(secruityProperties.getRpSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d"); authenticationManager.setSecruityProperties(secruityProperties); - systemManagement = mock(SystemManagement.class); - authenticationManager.setSystemManagement(systemManagement); + tenantConfigurationManagement = mock(TenantConfigurationManagement.class); + authenticationManager.setTenantConfigurationManagement(tenantConfigurationManagement); - when(systemManagement.getConfigurationValue(any(), eq(Boolean.class))).thenReturn(CONFIG_VALUE_FALSE); + when(tenantConfigurationManagement.getConfigurationValue(any(), eq(Boolean.class))).thenReturn(CONFIG_VALUE_FALSE); final ControllerManagement controllerManagement = mock(ControllerManagement.class); when(controllerManagement.getSecurityTokenByControllerId(anyString())).thenReturn(CONTROLLLER_ID); @@ -111,7 +111,7 @@ public class AmqpControllerAuthentficationTest { @Description("Tests authentication manager without wrong credential") public void testAuthenticationBadCredantialsWithWrongCredential() { final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); - when(systemManagement.getConfigurationValue( + when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID); @@ -128,7 +128,7 @@ public class AmqpControllerAuthentficationTest { @Description("Tests authentication successfull") public void testSuccessfullAuthentication() { final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); - when(systemManagement.getConfigurationValue( + when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID); @@ -160,7 +160,7 @@ public class AmqpControllerAuthentficationTest { public void testAuthenticationMessageBadCredantialsWithWrongCredential() { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); - when(systemManagement.getConfigurationValue( + when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID); @@ -182,7 +182,7 @@ public class AmqpControllerAuthentficationTest { public void testSuccessfullMessageAuthentication() { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345"); - when(systemManagement.getConfigurationValue( + when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID); diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java index 5782a48db..e4d79b3c4 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java @@ -18,7 +18,7 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -55,7 +55,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac private static final String CONTROLLER_DL_REQUEST_ANT_PATTERN = "/{" + TENANT_PLACE_HOLDER + "}/controller/artifacts/v1/**"; - protected SystemManagement systemManagement; + protected TenantConfigurationManagement tenantConfigurationManagement; protected TenantAware tenantAware; private final AntPathMatcher pathExtractor; @@ -70,9 +70,9 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac * @param tenantAware * the tenant aware service */ - public AbstractHttpControllerAuthenticationFilter(final SystemManagement systemManagement, + public AbstractHttpControllerAuthenticationFilter(final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware) { - this.systemManagement = systemManagement; + this.tenantConfigurationManagement = tenantConfigurationManagement; this.tenantAware = tenantAware; pathExtractor = new AntPathMatcher(); } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java index 91a0cdfa6..e18a90008 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.security; import org.eclipse.hawkbit.repository.ControllerManagement; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; /** @@ -45,15 +45,17 @@ public class HttpControllerPreAuthenticateSecurityTokenFilter extends AbstractHt * the controller management to retrieve the specific target * security token to verify */ - public HttpControllerPreAuthenticateSecurityTokenFilter(final SystemManagement systemManagement, - final TenantAware tenantAware, final ControllerManagement controllerManagement) { - super(systemManagement, tenantAware); + public HttpControllerPreAuthenticateSecurityTokenFilter( + final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, + final ControllerManagement controllerManagement) { + super(tenantConfigurationManagement, tenantAware); this.controllerManagement = controllerManagement; } @Override protected PreAuthenficationFilter createControllerAuthenticationFilter() { - return new ControllerPreAuthenticateSecurityTokenFilter(systemManagement, controllerManagement, tenantAware); + return new ControllerPreAuthenticateSecurityTokenFilter(tenantConfigurationManagement, controllerManagement, + tenantAware); } } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java index 2b1a4d78f..b62ac1db4 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -8,7 +8,7 @@ */ package org.eclipse.hawkbit.security; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; /** @@ -34,14 +34,14 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter * the tenant aware service to get configuration for the specific * tenant */ - public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(final SystemManagement systemManagement, - final TenantAware tenantAware) { - super(systemManagement, tenantAware); + public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter( + final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware) { + super(tenantConfigurationManagement, tenantAware); } @Override protected PreAuthenficationFilter createControllerAuthenticationFilter() { - return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(systemManagement, tenantAware); + return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(tenantConfigurationManagement, tenantAware); } } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java index 3d6b43657..5a67dda14 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java @@ -8,7 +8,7 @@ */ package org.eclipse.hawkbit.security; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; /** @@ -44,9 +44,9 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract * tenant */ public HttpControllerPreAuthenticatedSecurityHeaderFilter(final String caCommonNameHeader, - final String caAuthorityNameHeader, final SystemManagement systemManagement, + final String caAuthorityNameHeader, final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware) { - super(systemManagement, tenantAware); + super(tenantConfigurationManagement, tenantAware); this.caCommonNameHeader = caCommonNameHeader; this.caAuthorityNameHeader = caAuthorityNameHeader; } @@ -54,7 +54,7 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract @Override protected PreAuthenficationFilter createControllerAuthenticationFilter() { return new ControllerPreAuthenticatedSecurityHeaderFilter(caCommonNameHeader, caAuthorityNameHeader, - systemManagement, tenantAware); + tenantConfigurationManagement, tenantAware); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index e2d31a04c..16f2bb8ee 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -14,17 +14,15 @@ import java.util.Map; import org.eclipse.hawkbit.aspects.ExceptionMappingAspectHandler; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.helper.CacheManagerHolder; -import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder; import org.eclipse.hawkbit.repository.model.helper.SystemManagementHolder; import org.eclipse.hawkbit.repository.model.helper.TenantAwareHolder; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.tenancy.TenantAware; -import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration; -import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @@ -55,21 +53,13 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { /** - * @return simple default {@link AsyncUncaughtExceptionHandler} - * implementation - * @Bean public SimpleAsyncUncaughtExceptionHandler - * simpleAsyncUncaughtExceptionHandler() { return new - * SimpleAsyncUncaughtExceptionHandler(); } - * - * /** - * @return the {@link PollConfigurationHelper} singleton bean which holds - * the polling and polling overdue configuration and make it - * accessible in beans which cannot not be autowired or retrieve - * environment variables due {@link EnvironmentAware} interface. + * @return the {@link TenantConfigurationManagement} singleton bean which + * make it accessible in beans which cannot access the service + * directly, e.g. JPA entities. */ @Bean - public PollConfigurationHelper pollConfigurationHelper() { - return PollConfigurationHelper.getInstance(); + public TenantConfigurationManagement tenantConfigurationManagement() { + return TenantConfigurationManagement.getInstance(); } /** @@ -185,5 +175,4 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { public PlatformTransactionManager transactionManager() { return new MultiTenantJpaTransactionManager(); } - } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index 8cdc0f980..9c00acc7c 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -22,11 +22,8 @@ import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.TenantConfiguration; -import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.tenancy.TenantAware; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.persistence.config.PersistenceUnitProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; @@ -34,12 +31,7 @@ import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.SimpleKeyGenerator; -import org.springframework.context.EnvironmentAware; import org.springframework.context.annotation.Bean; -import org.springframework.core.convert.ConversionFailedException; -import org.springframework.core.convert.support.ConfigurableConversionService; -import org.springframework.core.convert.support.DefaultConversionService; -import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.Modifying; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; @@ -54,7 +46,7 @@ import org.springframework.validation.annotation.Validated; @Transactional(readOnly = true) @Validated @Service -public class SystemManagement implements EnvironmentAware { +public class SystemManagement { @Autowired private EntityManager entityManager; @@ -114,10 +106,6 @@ public class SystemManagement implements EnvironmentAware { private final ThreadLocal createInitialTenant = new ThreadLocal<>(); - private final ConfigurableConversionService conversionService = new DefaultConversionService(); - - private Environment environment; - /** * Calculated system usage statistics, both overall for the entire system * and per tenant; @@ -321,101 +309,6 @@ public class SystemManagement implements EnvironmentAware { return tenantMetaDataRepository.save(metaData); } - /** - * Retrieves a configuration value from the e.g. tenant overwritten - * configuration values or in case the tenant does not a have a specific - * configuration the global default value hold in the {@link Environment}. - * - * @param - * - * @param configurationKey - * the key of the configuration - * @param propertyType - * the type of the configuration value, e.g. {@code String.class} - * , {@code Integer.class}, etc - * @return the converted configuration value either from the tenant specific - * configuration stored or from the fallback default values or - * {@code null} in case key has not been configured and not default - * value exists - * @throws ConversionFailedException - * if the property cannot be converted to the given - * {@code propertyType} - */ - @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") - public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, - final Class propertyType) { - - final TenantConfiguration tenantConfiguration = tenantConfigurationRepository - .findByKey(configurationKey.getKeyName()); - - if (tenantConfiguration != null) { - return TenantConfigurationValue. builder().isGlobal(false).createdBy(tenantConfiguration.getCreatedBy()) - .createdAt(tenantConfiguration.getCreatedAt()) - .lastModifiedAt(tenantConfiguration.getLastModifiedAt()) - .lastModifiedBy(tenantConfiguration.getLastModifiedBy()) - .value(conversionService.convert(tenantConfiguration.getValue(), propertyType)).build(); - - } else if (configurationKey.getDefaultKeyName() != null) { - final T valueInProperties = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType); - - return TenantConfigurationValue. builder().isGlobal(true).createdBy(null).createdAt(null) - .lastModifiedAt(null).lastModifiedBy(null).value(valueInProperties != null ? valueInProperties - : conversionService.convert(configurationKey.getDefaultValue(), propertyType)) - .build(); - } - return null; - } - - /** - * Adds or updates a specific configuration for a specific tenant. - * - * @param tenantConf - * the tenant configuration object which contains the key and - * value of the specific configuration to update - * @return the added or updated TenantConfiguration - */ - @CacheEvict(value = "tenantConfiguration", key = "#tenantConf.getKey()") - @Transactional - @Modifying - public TenantConfiguration addOrUpdateConfiguration(final TenantConfiguration tenantConf) { - TenantConfiguration tenantConfiguration = tenantConfigurationRepository.findByKey(tenantConf.getKey()); - if (tenantConfiguration != null) { - tenantConfiguration.setValue(tenantConf.getValue()); - } else { - tenantConfiguration = new TenantConfiguration(tenantConf.getKey(), tenantConf.getValue()); - } - return tenantConfigurationRepository.save(tenantConfiguration); - } - - /** - * Deletes a specific configuration for the current tenant. - * - * @param configurationKey - * the configuration key to be deleted - */ - @CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") - @Transactional - @Modifying - public void deleteConfiguration(final TenantConfigurationKey configurationKey) { - tenantConfigurationRepository.deleteByKey(configurationKey.getKeyName()); - } - - @Transactional - public List getTenantConfigurations() { - return tenantConfigurationRepository.findAll(); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.context.EnvironmentAware#setEnvironment(org. - * springframework.core.env. Environment) - */ - @Override - public void setEnvironment(final Environment environment) { - this.environment = environment; - } - private DistributionSetType createStandardSoftwareDataSetup() { // Edge Controller Linux standard setup @@ -472,36 +365,5 @@ public class SystemManagement implements EnvironmentAware { return SimpleKeyGenerator.generateKey(initialTenantCreation.toUpperCase(), initialTenantCreation.toUpperCase()); } - } - - // @Transactional - // @Modifying - // public void updateTenantConfiguration(SystemConfigurationRequestBodyPut - // systemConReq) { - // - // DurationHelper dh = new DurationHelper(); - // - // TenantMetaData tenantMetaData = getTenantMetadata(); - // - // String ddstypeKey = systemConReq.getDefaultDistributionSetType(); - // - // if - // (distributionSetTypeRepository.findAll(DistributionSetTypeSpecification.byKey(ddstypeKey)).isEmpty()) - // { - // throw new InvalidDistributionSetTypeException( - // String.format("The specified default distribution set type %s doe not - // exist.", ddstypeKey)); - // } - // - // try { - // tenantMetaData.setPollingOverdueTime(dh.formattedStringToDuration(systemConReq.getPollingOverdueTime())); - // tenantMetaData.setPollingTime(dh.formattedStringToDuration(systemConReq.getPollingTime())); - // } catch (DateTimeParseException ex) { - // throw new InvalidPollingTimeException(ex); - // } - // - // updateTenantMetadata(tenantMetaData); - // } - } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java new file mode 100644 index 000000000..75210d9ef --- /dev/null +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -0,0 +1,125 @@ +package org.eclipse.hawkbit.repository; + +import java.util.List; + +import org.eclipse.hawkbit.repository.model.TenantConfiguration; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.EnvironmentAware; +import org.springframework.core.convert.ConversionFailedException; +import org.springframework.core.convert.support.ConfigurableConversionService; +import org.springframework.core.convert.support.DefaultConversionService; +import org.springframework.core.env.Environment; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +@Transactional(readOnly = true) +@Validated +public class TenantConfigurationManagement implements EnvironmentAware { + + private static final TenantConfigurationManagement INSTANCE = new TenantConfigurationManagement(); + + @Autowired + private TenantConfigurationRepository tenantConfigurationRepository; + + private final ConfigurableConversionService conversionService = new DefaultConversionService(); + + private Environment environment; + + public static TenantConfigurationManagement getInstance() { + return INSTANCE; + } + + /** + * Retrieves a configuration value from the e.g. tenant overwritten + * configuration values or in case the tenant does not a have a specific + * configuration the global default value hold in the {@link Environment}. + * + * @param + * + * @param configurationKey + * the key of the configuration + * @param propertyType + * the type of the configuration value, e.g. {@code String.class} + * , {@code Integer.class}, etc + * @return the converted configuration value either from the tenant specific + * configuration stored or from the fallback default values or + * {@code null} in case key has not been configured and not default + * value exists + * @throws ConversionFailedException + * if the property cannot be converted to the given + * {@code propertyType} + */ + @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") + public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, + final Class propertyType) { + + final TenantConfiguration tenantConfiguration = tenantConfigurationRepository + .findByKey(configurationKey.getKeyName()); + + if (tenantConfiguration != null) { + return TenantConfigurationValue. builder().isGlobal(false).createdBy(tenantConfiguration.getCreatedBy()) + .createdAt(tenantConfiguration.getCreatedAt()) + .lastModifiedAt(tenantConfiguration.getLastModifiedAt()) + .lastModifiedBy(tenantConfiguration.getLastModifiedBy()) + .value(conversionService.convert(tenantConfiguration.getValue(), propertyType)).build(); + + } else if (configurationKey.getDefaultKeyName() != null) { + final T valueInProperties = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType); + + return TenantConfigurationValue. builder().isGlobal(true).createdBy(null).createdAt(null) + .lastModifiedAt(null).lastModifiedBy(null).value(valueInProperties != null ? valueInProperties + : conversionService.convert(configurationKey.getDefaultValue(), propertyType)) + .build(); + } + return null; + } + + /** + * Adds or updates a specific configuration for a specific tenant. + * + * @param tenantConf + * the tenant configuration object which contains the key and + * value of the specific configuration to update + * @return the added or updated TenantConfiguration + */ + @CacheEvict(value = "tenantConfiguration", key = "#tenantConf.getKey()") + @Transactional + @Modifying + public TenantConfiguration addOrUpdateConfiguration(final TenantConfiguration tenantConf) { + TenantConfiguration tenantConfiguration = tenantConfigurationRepository.findByKey(tenantConf.getKey()); + if (tenantConfiguration != null) { + tenantConfiguration.setValue(tenantConf.getValue()); + } else { + tenantConfiguration = new TenantConfiguration(tenantConf.getKey(), tenantConf.getValue()); + } + return tenantConfigurationRepository.save(tenantConfiguration); + } + + /** + * Deletes a specific configuration for the current tenant. + * + * @param configurationKey + * the configuration key to be deleted + */ + @CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") + @Transactional + @Modifying + public void deleteConfiguration(final TenantConfigurationKey configurationKey) { + tenantConfigurationRepository.deleteByKey(configurationKey.getKeyName()); + } + + @Transactional + public List getTenantConfigurations() { + return tenantConfigurationRepository.findAll(); + } + + @Override + public void setEnvironment(final Environment environment) { + this.environment = environment; + } +} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index f00b4880e..2f221948f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -38,7 +38,9 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Transient; -import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.persistence.annotations.CascadeOnDelete; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -120,6 +122,9 @@ public class TargetInfo implements Persistable, Serializable { @Column(name = "request_controller_attributes", nullable = false) private boolean requestControllerAttributes = true; + @Transient + private final DurationHelper durationHelper = new DurationHelper(); + /** * Constructor for {@link TargetStatus}. * @@ -316,8 +321,13 @@ public class TargetInfo implements Persistable, Serializable { */ public PollStatus getPollStatus() { if (lastTargetQuery != null) { - final Duration pollTime = PollConfigurationHelper.getInstance().getPollTimeInterval(); - final Duration overdueTime = PollConfigurationHelper.getInstance().getOverduePollTimeInterval(); + final Duration pollTime = durationHelper.formattedStringToDuration(TenantConfigurationManagement + .getInstance().getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class) + .getValue()); + final Duration overdueTime = durationHelper + .formattedStringToDuration(TenantConfigurationManagement.getInstance() + .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) + .getValue()); final LocalDateTime currentDate = LocalDateTime.now(); final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), ZoneId.systemDefault()); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java index 140109596..48e1e2006 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java @@ -41,7 +41,7 @@ public class TenantConfigurationValue { * * @return the last modified at */ - public long getLastModifiedAt() { + public Long getLastModifiedAt() { return lastModifiedAt; } @@ -59,7 +59,7 @@ public class TenantConfigurationValue { * * @return the created at */ - public long getCreatedAt() { + public Long getCreatedAt() { return createdAt; } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java index 9d5fa2483..28356ef33 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java @@ -42,6 +42,7 @@ import org.eclipse.hawkbit.repository.TargetInfoRepository; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetRepository; import org.eclipse.hawkbit.repository.TargetTagRepository; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.TenantMetaDataRepository; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; @@ -180,6 +181,10 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @Autowired protected TenantAwareCacheManager cacheManager; + + @Autowired + protected TenantConfigurationManagement tenantConfigurationManagement; + @Autowired protected RolloutManagement rolloutManagement; diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java index a9461ff39..1a1632d32 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/SystemManagementTest.java @@ -21,10 +21,7 @@ import org.eclipse.hawkbit.report.model.TenantUsage; 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.model.TenantConfiguration; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.junit.Test; -import org.springframework.core.convert.ConversionFailedException; import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; @@ -151,93 +148,4 @@ public class SystemManagementTest extends AbstractIntegrationTestWithMongoDB { }); } - @Test - @Description("Tests that tenant specific configuration can be persisted and in case the tenant does not have specific configuration the default from environment is used instead.") - public void storeTenantSpecificConfiguration() { - final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; - final String envPropertyDefault = environment.getProperty(configKey.getDefaultKeyName()); - assertThat(envPropertyDefault).isNotNull(); - - // get the configuration from the system management - final String defaultConfigValue = systemManagement.getConfigurationValue(configKey, String.class).getValue(); - assertThat(envPropertyDefault).isEqualTo(defaultConfigValue); - - // update the tenant specific configuration - final String newConfigurationValue = "thisIsAnotherValueForPolling"; - assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue); - systemManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); - - // verify that new configuration value is used - final String updatedConfigurationValue = systemManagement.getConfigurationValue(configKey, String.class) - .getValue(); - assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); - assertThat(systemManagement.getTenantConfigurations()).hasSize(1); - } - - @Test - @Description("Tests that the tenant specific configuration can be updated") - public void updateTenantSpecifcConfiguration() { - final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; - final String value1 = "firstValue"; - final String value2 = "secondValue"; - - // add value first - systemManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value1)); - assertThat(systemManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value1); - - // update to value second - systemManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value2)); - assertThat(systemManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value2); - } - - @Test - @Description("Tests that the configuration value can be converted from String to Integer automatically") - public void tenantConfigurationValueConversion() { - final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; - final Integer value1 = 123; - systemManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), String.valueOf(value1))); - assertThat(systemManagement.getConfigurationValue(configKey, Integer.class).getValue()).isEqualTo(value1); - } - - @Test(expected = ConversionFailedException.class) - @Description("Tests that the get configuration throws exception in case the value cannot be automatically converted from String to Integer") - public void wrongTenantConfigurationValueConversionThrowsException() { - final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; - final String value1 = "thisIsNotANumber"; - // add value as String - systemManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), String.valueOf(value1))); - // try to get it as Integer - systemManagement.getConfigurationValue(configKey, Integer.class); - } - - @Test - @Description("Tests that a deletion of a tenant specific configuration deletes it from the database.") - public void deleteConfigurationReturnNullConfiguration() { - final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY; - - // gateway token does not have default value so no configuration value - // is should be available - final String defaultConfigValue = systemManagement.getConfigurationValue(configKey, String.class).getValue(); - assertThat(defaultConfigValue).isNull(); - - // update the tenant specific configuration - final String newConfigurationValue = "thisIsAnotherValueForPolling"; - assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue); - systemManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); - - // verify that new configuration value is used - final String updatedConfigurationValue = systemManagement.getConfigurationValue(configKey, String.class) - .getValue(); - assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); - - // delete the tenant specific configuration - systemManagement.deleteConfiguration(configKey); - // ensure that now gateway token is set again, because is deleted and - // must be null now - assertThat(systemManagement.getConfigurationValue(configKey, String.class).getValue()).isNull(); - } } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java new file mode 100644 index 000000000..73130407e --- /dev/null +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java @@ -0,0 +1,113 @@ +package org.eclipse.hawkbit.repository; + +import static org.fest.assertions.api.Assertions.assertThat; + +import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB; +import org.eclipse.hawkbit.repository.model.TenantConfiguration; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.junit.Test; +import org.springframework.core.convert.ConversionFailedException; + +import ru.yandex.qatools.allure.annotations.Description; +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +@Features("Component Tests - Repository") +@Stories("Tenant Configuration Management") +public class TenantConfigurationManagementTest extends AbstractIntegrationTestWithMongoDB { + + @Test + @Description("Tests that tenant specific configuration can be persisted and in case the tenant does not have specific configuration the default from environment is used instead.") + public void storeTenantSpecificConfiguration() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; + final String envPropertyDefault = environment.getProperty(configKey.getDefaultKeyName()); + assertThat(envPropertyDefault).isNotNull(); + + // get the configuration from the system management + final String defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class) + .getValue(); + assertThat(envPropertyDefault).isEqualTo(defaultConfigValue); + + // update the tenant specific configuration + final String newConfigurationValue = "thisIsAnotherValueForPolling"; + assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue); + tenantConfigurationManagement + .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); + + // verify that new configuration value is used + final String updatedConfigurationValue = tenantConfigurationManagement + .getConfigurationValue(configKey, String.class).getValue(); + assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); + assertThat(tenantConfigurationManagement.getTenantConfigurations()).hasSize(1); + } + + @Test + @Description("Tests that the tenant specific configuration can be updated") + public void updateTenantSpecifcConfiguration() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; + final String value1 = "firstValue"; + final String value2 = "secondValue"; + + // add value first + tenantConfigurationManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value1)); + assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()) + .isEqualTo(value1); + + // update to value second + tenantConfigurationManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value2)); + assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()) + .isEqualTo(value2); + } + + @Test + @Description("Tests that the configuration value can be converted from String to Integer automatically") + public void tenantConfigurationValueConversion() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; + final Integer value1 = 123; + tenantConfigurationManagement + .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), String.valueOf(value1))); + assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Integer.class).getValue()) + .isEqualTo(value1); + } + + @Test(expected = ConversionFailedException.class) + @Description("Tests that the get configuration throws exception in case the value cannot be automatically converted from String to Integer") + public void wrongTenantConfigurationValueConversionThrowsException() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; + final String value1 = "thisIsNotANumber"; + // add value as String + tenantConfigurationManagement + .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), String.valueOf(value1))); + // try to get it as Integer + tenantConfigurationManagement.getConfigurationValue(configKey, Integer.class); + } + + @Test + @Description("Tests that a deletion of a tenant specific configuration deletes it from the database.") + public void deleteConfigurationReturnNullConfiguration() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY; + + // gateway token does not have default value so no configuration value + // is should be available + final String defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class) + .getValue(); + assertThat(defaultConfigValue).isNull(); + + // update the tenant specific configuration + final String newConfigurationValue = "thisIsAnotherValueForPolling"; + assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue); + tenantConfigurationManagement + .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); + + // verify that new configuration value is used + final String updatedConfigurationValue = tenantConfigurationManagement + .getConfigurationValue(configKey, String.class).getValue(); + assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); + + // delete the tenant specific configuration + tenantConfigurationManagement.deleteConfiguration(configKey); + // ensure that now gateway token is set again, because is deleted and + // must be null now + assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isNull(); + } +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java index a73542afb..7416e55cc 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java @@ -17,16 +17,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class SystemConfigurationRest { @JsonProperty - private Map configuration; + private Map configuration; /** * Sets the authentication configuration. * - * @param authenticationConfiguration + * @param configuration * the authentication configuration */ - public void setAuthenticationConfiguration(Map authenticationConfiguration) { - this.configuration = authenticationConfiguration; + public void setConfiguration(final Map configuration) { + this.configuration = configuration; } /** @@ -34,7 +34,7 @@ public class SystemConfigurationRest { * * @return the authentication configuration */ - public Map getAuthenticationConfiguration() { + public Map getConfiguration() { return this.configuration; } } diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java new file mode 100644 index 000000000..78ebef8c3 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java @@ -0,0 +1,60 @@ +package org.eclipse.hawkbit.rest.resource.model.system; + +public class TenantConfigurationValueRest { + + private Object value = null; + private boolean isGlobal = true; + private Long lastModifiedAt = null; + private String lastModifiedBy = null; + private Long createdAt = null; + private String createdBy = null; + + public Object getValue() { + return value; + } + + public void setValue(final Object value) { + this.value = value; + } + + public boolean isGlobal() { + return isGlobal; + } + + public void setGlobal(final boolean isGlobal) { + this.isGlobal = isGlobal; + } + + public Long getLastModifiedAt() { + return lastModifiedAt; + } + + public void setLastModifiedAt(final Long lastModifiedAt) { + this.lastModifiedAt = lastModifiedAt; + } + + public String getLastModifiedBy() { + return lastModifiedBy; + } + + public void setLastModifiedBy(final String lastModifiedBy) { + this.lastModifiedBy = lastModifiedBy; + } + + public Long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(final Long createdAt) { + this.createdAt = createdAt; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(final String createdBy) { + this.createdBy = createdBy; + } + +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java index 6c4d86586..b533ff96a 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java @@ -17,10 +17,11 @@ import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.report.model.TenantUsage; import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfiguration; -import org.eclipse.hawkbit.rest.resource.model.system.AuthenticationConfigurationRest; import org.eclipse.hawkbit.rest.resource.model.system.CacheRest; import org.eclipse.hawkbit.rest.resource.model.system.SystemStatisticsRest; +import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationRest; import org.eclipse.hawkbit.rest.resource.model.system.TenantSystemUsageRest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,6 +54,9 @@ public class SystemManagementResource { @Autowired private SystemManagement systemManagement; + @Autowired + private TenantConfigurationManagement tenantConfigurationManagement; + @Autowired private CacheManager cacheManager; @@ -141,9 +145,9 @@ public class SystemManagementResource { */ @RequestMapping(method = RequestMethod.PUT, value = "/conf/{key}") @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) - public ResponseEntity addUpdateConfig(@RequestBody final AuthenticationConfigurationRest configuration, + public ResponseEntity addUpdateConfig(@RequestBody final TenantConfigurationRest configuration, @PathVariable final String key) { - systemManagement.addOrUpdateConfiguration(new TenantConfiguration(key, configuration.getValue())); + tenantConfigurationManagement.addOrUpdateConfiguration(new TenantConfiguration(key, configuration.getValue())); return ResponseEntity.ok().build(); } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java index a09f5fc73..75add4be5 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java @@ -3,11 +3,11 @@ package org.eclipse.hawkbit.rest.resource; import java.util.HashMap; import java.util.Map; -import org.eclipse.hawkbit.repository.SystemManagement; -import org.eclipse.hawkbit.repository.model.TenantMetaData; -import org.eclipse.hawkbit.repository.model.helper.DurationHelper; -import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRequestBodyPut; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRest; +import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationValueRest; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,25 +22,33 @@ final public class SystemMapper { private static DurationHelper dh = new DurationHelper(); - public static SystemConfigurationRest toResponse(final SystemManagement systemManagement) { + public static SystemConfigurationRest toResponse( + final TenantConfigurationManagement tenantConfigurationManagement) { final SystemConfigurationRest sysconf = new SystemConfigurationRest(); - final Map authconf = new HashMap(); + final Map authconf = new HashMap(); for (final TenantConfigurationKey key : TenantConfigurationKey.values()) { - final Object value = systemManagement.getConfigurationValue(key); + final TenantConfigurationValueRest value = toResponse( + tenantConfigurationManagement.getConfigurationValue(key, key.getDataType())); authconf.put(key.getKeyName(), value); } - sysconf.setAuthenticationConfiguration(authconf); + sysconf.setConfiguration(authconf); return sysconf; } - public static TenantMetaData fromRequest(final SystemManagement systemManagement, - final SystemConfigurationRequestBodyPut systemConReq) { + public static TenantConfigurationValueRest toResponse(final TenantConfigurationValue confValue) { + final TenantConfigurationValueRest response = new TenantConfigurationValueRest(); - // TODO - return null; + response.setValue(confValue.getValue()); + response.setGlobal(confValue.isGlobal()); + response.setCreatedAt(confValue.getCreatedAt()); + response.setCreatedBy(confValue.getCreatedBy()); + response.setLastModifiedAt(confValue.getLastModifiedAt()); + response.setLastModifiedBy(confValue.getLastModifiedBy()); + + return response; } } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java index 1b805cd43..888d3045a 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java @@ -1,7 +1,7 @@ package org.eclipse.hawkbit.rest.resource; import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRequestBodyPut; import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRest; import org.slf4j.Logger; @@ -22,7 +22,7 @@ public class SystemResource { private static final Logger LOGGER = LoggerFactory.getLogger(SystemResource.class); @Autowired - private SystemManagement systemManagement; + private TenantConfigurationManagement tenantConfigurationManagement; @Autowired private DistributionSetManagement distributionSetManagement; @@ -30,8 +30,7 @@ public class SystemResource { @RequestMapping(method = RequestMethod.GET, value = "/conf", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getSystemConfiguration() { - - return new ResponseEntity<>(SystemMapper.toResponse(systemManagement), HttpStatus.OK); + return new ResponseEntity<>(SystemMapper.toResponse(tenantConfigurationManagement), HttpStatus.OK); } @RequestMapping(method = RequestMethod.PUT, value = "/conf", consumes = { "application/hal+json", @@ -41,7 +40,7 @@ public class SystemResource { // systemManagement.updateTenantConfiguration(systemConReq); - return new ResponseEntity<>(SystemMapper.toResponse(systemManagement), HttpStatus.OK); + return new ResponseEntity<>(SystemMapper.toResponse(tenantConfigurationManagement), HttpStatus.OK); } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java index e35ac890b..552bbae06 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.security; import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; @@ -26,13 +26,13 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe private static final Logger LOGGER = LoggerFactory.getLogger(AbstractControllerAuthenticationFilter.class); - protected final SystemManagement systemManagement; + protected final TenantConfigurationManagement tenantConfigurationManagement; protected final TenantAware tenantAware; private final SecurityConfigurationKeyTenantRunner configurationKeyTenantRunner; - protected AbstractControllerAuthenticationFilter(final SystemManagement systemManagement, + protected AbstractControllerAuthenticationFilter(final TenantConfigurationManagement systemManagement, final TenantAware tenantAware) { - this.systemManagement = systemManagement; + this.tenantConfigurationManagement = systemManagement; this.tenantAware = tenantAware; this.configurationKeyTenantRunner = new SecurityConfigurationKeyTenantRunner(); } @@ -54,7 +54,8 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe @Override public Boolean run() { LOGGER.trace("retrieving configuration value for configuration key {}", getTenantConfigurationKey()); - return systemManagement.getConfigurationValue(getTenantConfigurationKey(), Boolean.class).getValue(); + return tenantConfigurationManagement.getConfigurationValue(getTenantConfigurationKey(), Boolean.class) + .getValue(); } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java index 3cf09cff8..c1dd49e0a 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java @@ -12,7 +12,7 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.repository.ControllerManagement; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; @@ -55,9 +55,10 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro * the tenant aware service to get configuration for the specific * tenant */ - public ControllerPreAuthenticateSecurityTokenFilter(final SystemManagement systemManagement, + public ControllerPreAuthenticateSecurityTokenFilter( + final TenantConfigurationManagement tenantConfigurationManagement, final ControllerManagement controllerManagement, final TenantAware tenantAware) { - super(systemManagement, tenantAware); + super(tenantConfigurationManagement, tenantAware); this.controllerManagement = controllerManagement; } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java index 1e890e33d..95308d671 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.security; import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; @@ -46,9 +46,9 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra * the tenant aware service to get configuration for the specific * tenant */ - public ControllerPreAuthenticatedGatewaySecurityTokenFilter(final SystemManagement systemManagement, - final TenantAware tenantAware) { - super(systemManagement, tenantAware); + public ControllerPreAuthenticatedGatewaySecurityTokenFilter( + final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware) { + super(tenantConfigurationManagement, tenantAware); } @Override @@ -84,7 +84,7 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra public String run() { LOGGER.trace("retrieving configuration value for configuration key {}", TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY); - return systemManagement.getConfigurationValue( + return tenantConfigurationManagement.getConfigurationValue( TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue(); } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java index 369b618e7..21289b71c 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.security; import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; @@ -65,9 +65,9 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont * tenant */ public ControllerPreAuthenticatedSecurityHeaderFilter(final String caCommonNameHeader, - final String caAuthorityNameHeader, final SystemManagement systemManagement, + final String caAuthorityNameHeader, final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware) { - super(systemManagement, tenantAware); + super(tenantConfigurationManagement, tenantAware); this.caCommonNameHeader = caCommonNameHeader; this.sslIssuerHashBasicHeader = caAuthorityNameHeader; } @@ -142,7 +142,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont private final class GetSecurityAuthorityNameTenantRunner implements TenantAware.TenantRunner { @Override public String run() { - return systemManagement.getConfigurationValue( + return tenantConfigurationManagement.getConfigurationValue( TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class).getValue(); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 80865410c..3e3c84fcc 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -5,10 +5,10 @@ import java.time.Duration; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ControllerPollProperties; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.repository.model.helper.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.tenantconfiguration.polling.DurationConfigField; import org.eclipse.hawkbit.ui.utils.I18N; @@ -40,7 +40,7 @@ public class PollingConfigurationView extends BaseConfigurationView private ControllerPollProperties controllerPollProperties; @Autowired - private transient SystemManagement systemManagement; + private transient TenantConfigurationManagement tenantConfigurationManagement; private DurationConfigField fieldPollTime = null; private DurationConfigField fieldPollingOverdueTime = null; @@ -66,13 +66,13 @@ public class PollingConfigurationView extends BaseConfigurationView globalPollTime = durationHelper.formattedStringToDuration(controllerPollProperties.getPollingTime()); globalOverdueTime = durationHelper.formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); - final TenantConfigurationValue pollTimeConfValue = systemManagement + final TenantConfigurationValue pollTimeConfValue = tenantConfigurationManagement .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class); if (!pollTimeConfValue.isGlobal()) { tenantPollTime = durationHelper.formattedStringToDuration(pollTimeConfValue.getValue()); } - final TenantConfigurationValue overdueTimeConfValue = systemManagement + final TenantConfigurationValue overdueTimeConfValue = tenantConfigurationManagement .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class); if (!overdueTimeConfValue.isGlobal()) { tenantOverdueTime = durationHelper.formattedStringToDuration(overdueTimeConfValue.getValue()); @@ -97,7 +97,7 @@ public class PollingConfigurationView extends BaseConfigurationView fieldPollingOverdueTime = DurationConfigField.builder().caption(i18n.get("configuration.polling.overduetime")) .checkBoxLabel(i18n.get("configuration.polling.custom.value")).range(minDuration, maxDuration) - .globalDuration(globalPollTime).tenantDuration(tenantOverdueTime).build(); + .globalDuration(globalOverdueTime).tenantDuration(tenantOverdueTime).build(); fieldPollingOverdueTime.addChangeListener(this); vLayout.addComponent(fieldPollingOverdueTime); @@ -111,14 +111,14 @@ public class PollingConfigurationView extends BaseConfigurationView if (!compareDurations(tenantPollTime, fieldPollTime.getValue())) { tenantPollTime = fieldPollTime.getValue(); - systemManagement.addOrUpdateConfiguration( + tenantConfigurationManagement.addOrUpdateConfiguration( new TenantConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL.getKeyName(), durationHelper.durationToFormattedString(tenantPollTime))); } if (!compareDurations(tenantOverdueTime, fieldPollingOverdueTime.getValue())) { tenantOverdueTime = fieldPollingOverdueTime.getValue(); - systemManagement.addOrUpdateConfiguration( + tenantConfigurationManagement.addOrUpdateConfiguration( new TenantConfiguration(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL.getKeyName(), durationHelper.durationToFormattedString(tenantOverdueTime))); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java index f71adaaf2..feb7e772c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; import java.util.ArrayList; import java.util.List; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; @@ -34,20 +34,21 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay private static final long serialVersionUID = 1L; private final TenantConfigurationKey configurationKey; - private final transient SystemManagement systemManagement; + private final transient TenantConfigurationManagement tenantConfigurationManagement; private final List configurationChangeListeners = new ArrayList<>(); /** * @param configurationKey * the key for this configuration - * @param systemManagement - * the system management to retrive the configuration value + * @param tenantConfigurationManagement + * the tenant configuration management to retrieve the + * configuration value */ public AbstractAuthenticationTenantConfigurationItem(final TenantConfigurationKey configurationKey, - final SystemManagement systemManagement) { + final TenantConfigurationManagement tenantConfigurationManagement) { this.configurationKey = configurationKey; - this.systemManagement = systemManagement; + this.tenantConfigurationManagement = tenantConfigurationManagement; } /** @@ -66,15 +67,16 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay */ @Override public boolean isConfigEnabled() { - final boolean b = systemManagement.getConfigurationValue(configurationKey, Boolean.class).getValue(); + final boolean b = tenantConfigurationManagement.getConfigurationValue(configurationKey, Boolean.class) + .getValue(); return b; } /** * @return the systemManagement */ - protected SystemManagement getSystemManagement() { - return systemManagement; + protected TenantConfigurationManagement getTenantConfigurationManagement() { + return tenantConfigurationManagement; } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java index b4210b6fb..0263b202e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; import javax.annotation.PostConstruct; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -54,8 +54,9 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti * the system management to retrie the configuration */ @Autowired - public CertificateAuthenticationConfigurationItem(final SystemManagement systemManagement) { - super(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED, systemManagement); + public CertificateAuthenticationConfigurationItem( + final TenantConfigurationManagement tenantConfigurationManagement) { + super(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED, tenantConfigurationManagement); } /** @@ -133,12 +134,12 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti @Override public void save() { if (configurationEnabledChange) { - getSystemManagement().addOrUpdateConfiguration( + getTenantConfigurationManagement().addOrUpdateConfiguration( new TenantConfiguration(getConfigurationKey().getKeyName(), String.valueOf(configurationEnabled))); } if (configurationCaRootAuthorityChanged) { final String value = caRootAuthorityTextField.getValue() != null ? caRootAuthorityTextField.getValue() : ""; - getSystemManagement().addOrUpdateConfiguration(new TenantConfiguration( + getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME.getKeyName(), value)); } } @@ -153,13 +154,13 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti configurationEnabledChange = false; configurationCaRootAuthorityChanged = false; - configurationEnabled = getSystemManagement().getConfigurationValue(getConfigurationKey(), Boolean.class) - .getValue(); + configurationEnabled = getTenantConfigurationManagement() + .getConfigurationValue(getConfigurationKey(), Boolean.class).getValue(); caRootAuthorityTextField.setValue(getCaRootAuthorityValue()); } private String getCaRootAuthorityValue() { - return getSystemManagement() + return getTenantConfigurationManagement() .getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, String.class) .getValue(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java index c9fb175b8..556d4e08c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; import javax.annotation.PostConstruct; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; @@ -66,8 +66,9 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac * @param systemManagement */ @Autowired - public GatewaySecurityTokenAuthenticationConfigurationItem(final SystemManagement systemManagement) { - super(TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED, systemManagement); + public GatewaySecurityTokenAuthenticationConfigurationItem( + final TenantConfigurationManagement tenantConfigurationManagement) { + super(TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED, tenantConfigurationManagement); } /** @@ -167,12 +168,12 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac } private String getSecurityTokenName() { - return getSystemManagement().getConfigurationValue( + return getTenantConfigurationManagement().getConfigurationValue( TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME, String.class).getValue(); } private String getSecurityTokenKey() { - return getSystemManagement().getConfigurationValue( + return getTenantConfigurationManagement().getConfigurationValue( TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue(); } @@ -188,18 +189,18 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac @Override public void save() { if (configurationEnabledChange) { - getSystemManagement().addOrUpdateConfiguration(new TenantConfiguration( + getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED.getKeyName(), String.valueOf(configurationEnabled))); } if (keyNameChanged) { - getSystemManagement().addOrUpdateConfiguration(new TenantConfiguration( + getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME.getKeyName(), gatewayTokenNameTextField.getValue())); } if (keyChanged) { - getSystemManagement().addOrUpdateConfiguration(new TenantConfiguration( + getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY.getKeyName(), gatewayTokenkeyLabel.getValue())); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java index 768ee1d92..4e9bd0572 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; import javax.annotation.PostConstruct; -import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.utils.I18N; @@ -44,8 +44,9 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract * the system management to retrie the configuration */ @Autowired - public TargetSecurityTokenAuthenticationConfigurationItem(final SystemManagement systemManagement) { - super(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED, systemManagement); + public TargetSecurityTokenAuthenticationConfigurationItem( + final TenantConfigurationManagement tenantConfigurationManagement) { + super(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED, tenantConfigurationManagement); } /** @@ -88,7 +89,7 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract @Override public void save() { if (configurationEnabledChange) { - getSystemManagement().addOrUpdateConfiguration( + getTenantConfigurationManagement().addOrUpdateConfiguration( new TenantConfiguration(getConfigurationKey().getKeyName(), String.valueOf(configurationEnabled))); } } @@ -96,7 +97,7 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract @Override public void undo() { configurationEnabledChange = false; - configurationEnabled = getSystemManagement().getConfigurationValue(getConfigurationKey(), Boolean.class) - .getValue(); + configurationEnabled = getTenantConfigurationManagement() + .getConfigurationValue(getConfigurationKey(), Boolean.class).getValue(); } } From 49486755b2f2f43dc4591da4bde16a7a258e74f0 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Wed, 27 Jan 2016 17:24:43 +0100 Subject: [PATCH 16/42] Revert "changed datamodel, integrated poll configuration into tenant meta data table" This reverts commit 9d147aada710cc2333723604fa8893e4f2f0515f. Signed-off-by: Nonnenmacher Fabian Conflicts: hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java --- .../hawkbit/ControllerPollProperties.java | 3 +++ .../repository/model/TenantMetaData.java | 27 ------------------- ...0__update_target_meta_for_polling___H2.sql | 2 -- ...pdate_target_meta_for_polling___MYSQL2.sql | 3 --- 4 files changed, 3 insertions(+), 32 deletions(-) delete mode 100644 hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql delete mode 100644 hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java index 51a4f9ff1..e66d86801 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java @@ -13,6 +13,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; /** * Defines the polling time for the controllers in HH:MM:SS notation. * + * + * */ @ConfigurationProperties(prefix = "hawkbit.controller") @@ -54,4 +56,5 @@ public class ControllerPollProperties { public void setMinPollingTime(String minPollingTime) { this.minPollingTime = minPollingTime; } + } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java index a83004ead..e86bfe8a4 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantMetaData.java @@ -9,7 +9,6 @@ package org.eclipse.hawkbit.repository.model; import java.io.Serializable; -import java.time.Duration; import javax.persistence.Access; import javax.persistence.AccessType; @@ -25,11 +24,9 @@ import javax.persistence.Index; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; -import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import javax.persistence.Version; -import org.eclipse.hawkbit.repository.model.helper.DurationHelper; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; @@ -63,12 +60,6 @@ public class TenantMetaData implements Serializable { @Column(name = "tenant", nullable = false, length = 40) private String tenant; - @Column(name = "polling_time", nullable = true, length = 10) - private String pollingTime; - - @Column(name = "polling_overdue_time", nullable = true, length = 10) - private String pollingOverdueTime; - private String createdBy; private String lastModifiedBy; private Long createdAt; @@ -86,9 +77,6 @@ public class TenantMetaData implements Serializable { // "fk_tenant_md_default_ds_type" ) private DistributionSetType defaultDsType; - @Transient - private DurationHelper dh = new DurationHelper(); - public TenantMetaData() { } @@ -268,19 +256,4 @@ public class TenantMetaData implements Serializable { return true; } - public Duration getPollingTime() { - return dh.formattedStringToDuration(pollingTime); - } - - public void setPollingTime(Duration pollingTime) { - this.pollingTime = dh.durationToFormattedString(pollingTime); - } - - public Duration getPollingOverdueTime() { - return dh.formattedStringToDuration(pollingOverdueTime); - } - - public void setPollingOverdueTime(Duration pollingOverdueTime) { - this.pollingOverdueTime = dh.durationToFormattedString(pollingOverdueTime); - } } diff --git a/hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql b/hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql deleted file mode 100644 index 17ec505bf..000000000 --- a/hawkbit-repository/src/main/resources/db/migration/H2/V1_6_0__update_target_meta_for_polling___H2.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE sp_tenant ADD polling_time varchar(10); -ALTER TABLE sp_tenant ADD polling_overdue_time varchar(10); diff --git a/hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql b/hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql deleted file mode 100644 index 3f0aadde6..000000000 --- a/hawkbit-repository/src/main/resources/db/migration/MYSQL/V1_6_0__update_target_meta_for_polling___MYSQL2.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE sp_tenant ADD polling_time varchar(10); -ALTER TABLE sp_tenant ADD polling_overdue_time varchar(10); - From a5a0dc17f604841b844cbb9084cfa32da0c3c9dc Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Wed, 27 Jan 2016 17:51:27 +0100 Subject: [PATCH 17/42] Removed PollConfigurationHelper and not used Exceptions - removed PollConfigurationHelper and coresspending test, because it was replaced by TenantConfigurationManagement - removed very specific configuration exceptions, because they are not needed anymore Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/exception/SpServerError.java | 12 - .../InvalidDistributionSetTypeException.java | 40 --- .../InvalidPollingTimeException.java | 35 --- .../model/helper/PollConfigurationHelper.java | 255 ------------------ .../PollConfigurationHelperTest.java | 147 ---------- 5 files changed, 489 deletions(-) delete mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java delete mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java delete mode 100644 hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java delete mode 100644 hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.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 9ba75835d..9f374bb7c 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 @@ -66,18 +66,6 @@ public enum SpServerError { SP_REST_SORT_PARAM_INVALID_DIRECTION("hawkbit.server.error.rest.param.invalidDirection", "The given sort parameter direction does not exist"), - /** - * - */ - SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED("hawkbit.server.error.rest.param.invalidFormat", - "The given overdue polling time or polling time parameter are not formatted correctly."), - - /** - * - */ - SP_REST_CONFIG_INVALID_DS_TYPE("hawkbit.server.error.rest.param.invalidFormat", - "The given default distribution set type does not exist."), - /** * */ diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java deleted file mode 100644 index 42fbe9c3c..000000000 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidDistributionSetTypeException.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.eclipse.hawkbit.repository.exception; - -import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; - -/** - * This Exception is thrown, when the user wants to set a distribution set which - * does not exist, - * - */ -public class InvalidDistributionSetTypeException extends SpServerRtException { - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Creates a new CancelActionNotAllowed with - * {@link SpServerError#SP_ACTION_NOT_CANCELABLE} error. - */ - public InvalidDistributionSetTypeException() { - super(SpServerError.SP_REST_CONFIG_INVALID_DS_TYPE); - } - - /** - * @param cause - * for the exception - */ - public InvalidDistributionSetTypeException(final Throwable cause) { - super(SpServerError.SP_REST_CONFIG_INVALID_DS_TYPE, cause); - } - - /** - * @param message - * of the error - */ - public InvalidDistributionSetTypeException(final String message) { - super(message, SpServerError.SP_REST_CONFIG_INVALID_DS_TYPE); - } -} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java deleted file mode 100644 index 818401563..000000000 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidPollingTimeException.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.eclipse.hawkbit.repository.exception; - -import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; - -public class InvalidPollingTimeException extends SpServerRtException { - /** - * - */ - private static final long serialVersionUID = 1L; - - /** - * Creates a new CancelActionNotAllowed with - * {@link SpServerError#SP_ACTION_NOT_CANCELABLE} error. - */ - public InvalidPollingTimeException() { - super(SpServerError.SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED); - } - - /** - * @param cause - * for the exception - */ - public InvalidPollingTimeException(final Throwable cause) { - super(SpServerError.SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED, cause); - } - - /** - * @param message - * of the error - */ - public InvalidPollingTimeException(final String message) { - super(message, SpServerError.SP_REST_CONFIG_POLLING_TIME_WRONG_FOMRATTED); - } -} diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java deleted file mode 100644 index 55f9395b0..000000000 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/helper/PollConfigurationHelper.java +++ /dev/null @@ -1,255 +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.repository.model.helper; - -import java.time.Duration; -import java.time.format.DateTimeParseException; - -import javax.annotation.PostConstruct; -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.ControllerPollProperties; -import org.eclipse.hawkbit.repository.SystemManagement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.EnvironmentAware; - -/** - * A singleton bean which holds configuration of the poll time - * {@code hawkbit.server.controller.polling} and - * {@code hawkbit.server.controller.polling.overdue} to have access to the - * configuration in beans not instatinated by spring e.g. JPA entities which - * cannot implement the {@link EnvironmentAware} interface to retrieve - * environment variables. - */ -public final class PollConfigurationHelper { - - /** - * Format of the expected Duration String. Pattern has to be in Valid Format - * for SimpleDateFormat - */ - - private static final Logger LOG = LoggerFactory.getLogger(PollConfigurationHelper.class); - private static final PollConfigurationHelper INSTANCE = new PollConfigurationHelper(); - - private static final int DEFAULT_OVERDUE_HOUR = 0; - private static final int DEFAULT_OVERDUE_MINUTE = 5; - private static final int DEFAULT_OVERDUE_SECOND = 0; - - private static final int DEFAULT_POLL_HOUR = 0; - private static final int DEFAULT_POLL_MINUTE = 5; - private static final int DEFAULT_POLL_SECOND = 0; - - private static final int DEFAULT_MAX_HOUR = 23; - private static final int DEFAULT_MAX_MINUTE = 59; - private static final int DEFAULT_MAX_SECOND = 59; - - private static final int DEFAULT_MIN_HOUR = 0; - private static final int DEFAULT_MIN_MINUTE = 0; - private static final int DEFAULT_MIN_SECOND = 30; - - private static DurationHelper dh = new DurationHelper(); - - @Autowired - private ControllerPollProperties controllerPollProperties; - - @Autowired - private SystemManagement systemManagement; - - private Duration configurationPollTime; - private Duration configurationOverduePollTime; - private Duration configurationMaximumPollTime; - private Duration configurationMinimumPollTime; - - /** - * @return a singleton instance of the environment helper. - */ - public static PollConfigurationHelper getInstance() { - return INSTANCE; - } - - /** - * Bean post construct to calculate the poll time and poll overdue time only - * once. - */ - @PostConstruct - public void initializeConfigurationValues() { - - readGlobalDurationsFromConfiguration(); - - validateGlobalDurations(); - } - - private void readGlobalDurationsFromConfiguration() { - try { - configurationMaximumPollTime = dh.formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); - } catch (DateTimeParseException e) { - // Set to default values - configurationMaximumPollTime = dh.getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, - DEFAULT_MAX_SECOND); - } - - try { - configurationMinimumPollTime = dh.formattedStringToDuration(controllerPollProperties.getMinPollingTime()); - } catch (DateTimeParseException e) { - // Set to default values - configurationMinimumPollTime = dh.getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, - DEFAULT_MIN_SECOND); - } - - try { - configurationPollTime = dh.formattedStringToDuration(controllerPollProperties.getPollingTime()); - } catch (DateTimeParseException e) { - configurationPollTime = dh.getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, - DEFAULT_POLL_SECOND); - } - - try { - configurationOverduePollTime = dh - .formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); - } catch (DateTimeParseException e) { - configurationOverduePollTime = dh.getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, - DEFAULT_OVERDUE_SECOND); - } - - } - - private void validateGlobalDurations() { - - if (configurationMaximumPollTime.compareTo(configurationMinimumPollTime) < 0) { - // min value > max value -> use default values for both durations - LOG.warn("The configured maximum value of the polling time is smaller" - + " than the configured minimum value. Both are replaced by default values."); - - configurationMaximumPollTime = dh.getDurationByTimeValues(DEFAULT_MAX_HOUR, DEFAULT_MAX_MINUTE, - DEFAULT_MAX_SECOND); - configurationMinimumPollTime = dh.getDurationByTimeValues(DEFAULT_MIN_HOUR, DEFAULT_MIN_MINUTE, - DEFAULT_MIN_SECOND); - } - - if (!isWithinRange(configurationPollTime)) { - // poll time value not within allowed range ==> use default value - configurationPollTime = dh.getDurationByTimeValues(DEFAULT_POLL_HOUR, DEFAULT_POLL_MINUTE, - DEFAULT_POLL_SECOND); - } - - if (!isWithinRange(configurationOverduePollTime)) { - // overdue poll time value not within range => use default value - configurationOverduePollTime = dh.getDurationByTimeValues(DEFAULT_OVERDUE_HOUR, DEFAULT_OVERDUE_MINUTE, - DEFAULT_OVERDUE_SECOND); - } - } - - private boolean isWithinRange(@NotNull Duration duration) { - return duration.compareTo(configurationMinimumPollTime) > 0 - && duration.compareTo(configurationMaximumPollTime) < 0; - } - - /** - * @return the poll time interval stored in the tenant meta data. If there - * is no tenant specific configuration the global value, configured - * in the configuration {@code hawkbit.server.controller.polling} or - * the default value which is {@code 00:05:00} never {@code null}. - */ - public Duration getPollTimeInterval() { - Duration tenantPollTimeInterval = systemManagement.getTenantMetadata().getPollingTime(); - - if (tenantPollTimeInterval != null) { - if (isWithinRange(tenantPollTimeInterval)) { - return tenantPollTimeInterval; - } - LOG.warn( - "Tenant {} has stored a pollign interval {} which is not in the allowed range. Configured default value is loaded.", - systemManagement.currentTenant(), tenantPollTimeInterval); - } - return configurationPollTime; - } - - /** - * @return the poll time interval configured in the configuration - * {@code hawkbit.server.controller.polling} or the default value - * which is {@code 00:05:00} never {@code null}. This method ignores - * eventual tenant specific configurations. - */ - public Duration getGlobalPollTimeInterval() { - return configurationPollTime; - } - - /** - * @return the overdue poll time interval stored in the tenant meta data. If - * there is no tenant specific configuration the global value, - * configured in the configuration - * {@code hawkbit.server.controller.polling} or the default value - * which is {@code 00:05:00} never {@code null}. - */ - public Duration getOverduePollTimeInterval() { - Duration tenantOverduePollTimeInterval = systemManagement.getTenantMetadata().getPollingOverdueTime(); - - if (tenantOverduePollTimeInterval != null) { - if (isWithinRange(tenantOverduePollTimeInterval)) { - return tenantOverduePollTimeInterval; - } - LOG.warn( - "Tenant {} has stored an overdue polling interval {} which is not in the allowed range. Configured default value is loaded.", - systemManagement.currentTenant(), tenantOverduePollTimeInterval); - } - return configurationOverduePollTime; - }; - - /** - * @return the overdue poll time interval configured in the configuration - * {@code hawkbit.server.controller.polling.overdue} or the default - * value which is {@code 00:05:00} never {@code null}. - */ - public Duration getGlobalOverduePollTimeInterval() { - return configurationOverduePollTime; - } - - /** - * @return the maximum poll time duration configured in the configuration - * {@code hawkbit.server.controller.polling.overdue} or the default - * value which is {@code 23:59:00} never {@code null}. - */ - public Duration getMaximumPollingInterval() { - return configurationMaximumPollTime; - } - - /** - * @return the minimum poll time duration configured in the configuration - * {@code hawkbit.server.controller.polling.overdue} or the default - * value which is {@code 23:59:00} never {@code null}. - */ - public Duration getMinimumPollingInterval() { - return configurationMinimumPollTime; - } - - /** - * sets the ControllerPollProperties in a not spring handled context. Don't - * forget to call {@code initializeConfigurationValues} afterwards to read - * the values from the PollProperties. - * - * @param controllerPollProperties - * the controller poll properties - */ - public void setControllerPollProperties(ControllerPollProperties controllerPollProperties) { - this.controllerPollProperties = controllerPollProperties; - } - - /** - * sets the SystemManagement instance which is responsible for tenant - * specific configuration. - * - * @param systemManagement - * the SystemManagemnt instance - */ - public void setSystemManagement(SystemManagement systemManagement) { - this.systemManagement = systemManagement; - } -} diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java deleted file mode 100644 index 4ee6e92f9..000000000 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/PollConfigurationHelperTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.eclipse.hawkbit.repository; - -import static org.fest.assertions.api.Assertions.assertThat; -import static org.mockito.Mockito.when; - -import java.time.Duration; - -import org.eclipse.hawkbit.ControllerPollProperties; -import org.eclipse.hawkbit.repository.model.TenantMetaData; -import org.eclipse.hawkbit.repository.model.helper.DurationHelper; -import org.eclipse.hawkbit.repository.model.helper.PollConfigurationHelper; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -@RunWith(MockitoJUnitRunner.class) -public class PollConfigurationHelperTest { - - @Mock - private ControllerPollProperties controllerPollProperties; - - @Mock - private SystemManagement systemManagement; - - @Mock - private TenantMetaData tenantMetaData; - - private PollConfigurationHelper pollConfigurationHelperUnderTest; - - private static final Duration DEFAULT_MIN = Duration.ofSeconds(30); - private static final Duration DEFAULT_MAX = Duration.ofHours(23).plusMinutes(59).plusSeconds(59); - private static final Duration DEFAULT_POLLING = Duration.ofMinutes(5); - private static final Duration DEFAULT_OVERDUE = Duration.ofMinutes(5); - - @Before - public void initMocks() { - - pollConfigurationHelperUnderTest = PollConfigurationHelper.getInstance(); - - setConfigurationValues("00:05:00", "00:05:00", "00:00:30", "23:59:59"); - setTenantConfiguration(null, null); - } - - private void setConfigurationValues(String polling, String overdue, String min, String max) { - when(controllerPollProperties.getPollingTime()).thenReturn(polling); - when(controllerPollProperties.getPollingOverdueTime()).thenReturn(overdue); - when(controllerPollProperties.getMinPollingTime()).thenReturn(min); - when(controllerPollProperties.getMaxPollingTime()).thenReturn(max); - - pollConfigurationHelperUnderTest.setControllerPollProperties(controllerPollProperties); - pollConfigurationHelperUnderTest.initializeConfigurationValues(); - } - - private void setTenantConfiguration(Duration polling, Duration overdue) { - - when(tenantMetaData.getPollingTime()).thenReturn(polling); - when(tenantMetaData.getPollingOverdueTime()).thenReturn(overdue); - - when(systemManagement.getTenantMetadata()).thenReturn(tenantMetaData); - - pollConfigurationHelperUnderTest.setSystemManagement(systemManagement); - } - - @Test - public void getCorrectConfigurationValues() { - - setConfigurationValues("00:08:00", "00:12:00", "00:01:00", "20:00:00"); - - assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(Duration.ofHours(20)); - assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(Duration.ofMinutes(1)); - assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(Duration.ofMinutes(8)); - assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()) - .isEqualTo(Duration.ofMinutes(12)); - - assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(Duration.ofMinutes(8)); - assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(12)); - } - - @Test - public void getWrongFromattedConfiguratonValues() { - setConfigurationValues("00-08:00", "abc", "12:00:000", "20hours"); - - assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(DEFAULT_MAX); - assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(DEFAULT_MIN); - assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(DEFAULT_POLLING); - assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); - } - - @Test - public void getMinimumGreaterMaximum() { - setConfigurationValues("00:07:00", "00:07:00", "01:00:00", "00:00:00"); - - assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(DEFAULT_MAX); - assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(DEFAULT_MIN); - assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(Duration.ofMinutes(7)); - assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()) - .isEqualTo(Duration.ofMinutes(7)); - } - - @Test - public void getPollConfigurationNotWithinRange() { - setConfigurationValues("22:00:00", "00:07:00", "01:00:00", "10:00:00"); - - assertThat(pollConfigurationHelperUnderTest.getMaximumPollingInterval()).isEqualTo(Duration.ofHours(10)); - assertThat(pollConfigurationHelperUnderTest.getMinimumPollingInterval()).isEqualTo(Duration.ofHours(1)); - assertThat(pollConfigurationHelperUnderTest.getGlobalPollTimeInterval()).isEqualTo(DEFAULT_POLLING); - assertThat(pollConfigurationHelperUnderTest.getGlobalOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); - } - - @Test - public void getPollingValuesFromTenant() { - - setTenantConfiguration(Duration.ofMinutes(11), Duration.ofMinutes(17)); - - assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(Duration.ofMinutes(11)); - assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(Duration.ofMinutes(17)); - - } - - @Test - public void getInvalidPollingValuesFromTenant() { - - setTenantConfiguration(Duration.ZERO, Duration.ofHours(30)); - - assertThat(pollConfigurationHelperUnderTest.getPollTimeInterval()).isEqualTo(DEFAULT_POLLING); - assertThat(pollConfigurationHelperUnderTest.getOverduePollTimeInterval()).isEqualTo(DEFAULT_OVERDUE); - - } - - @Test - public void basicTestingOfDurationHelper() { - DurationHelper dh = new DurationHelper(); - - assertThat(dh.durationToFormattedString(null)).isNull(); - assertThat(dh.durationToFormattedString(Duration.ofHours(1).plusMinutes(2).plusSeconds(1))) - .isEqualTo("01:02:01"); - - assertThat(dh.formattedStringToDuration(null)).isNull(); - assertThat(dh.formattedStringToDuration("01:02:01")) - .isEqualTo(Duration.ofHours(1).plusMinutes(2).plusSeconds(1)); - - assertThat(dh.getDurationByTimeValues(0, 0, 0)).isEqualTo(Duration.ZERO); - - } -} From d83286c94a4dcfca2262b978ccaa05431cf7a42c Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 28 Jan 2016 15:17:12 +0100 Subject: [PATCH 18/42] Changed validation method to throw exception/SpServerError * changed error handling from return value to throw exceptions, to give the user a feedback what was wrong * added ValidationException to ResponseExceptionHandler, to map the correct REST status codes Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/exception/SpServerError.java | 6 ++ .../configuration/TenantConfigurationKey.java | 48 +++++++++----- .../validator/BooleanValidator.java | 13 ---- .../validator/PollTimeValidator.java | 47 -------------- .../validator/StringValidator.java | 13 ---- .../TenantConfigurationBooleanValidator.java | 18 ++++++ ...ConfigurationPollingDurationValidator.java | 62 +++++++++++++++++++ .../TenantConfigurationStringValidator.java | 17 +++++ .../TenantConfigurationValidator.java | 16 ++++- ...TenantConfigurationValidatorException.java | 55 ++++++++++++++++ .../resource/ResponseExceptionHandler.java | 1 + 11 files changed, 206 insertions(+), 90 deletions(-) delete mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java delete mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java delete mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/exceptions/TenantConfigurationValidatorException.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 9f374bb7c..068edf80c 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 @@ -177,6 +177,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_CONFIGURATION_VALUE_INVALID("hawkbit.server.error.configValueInvalid", + "The given configuration value is invalid."); + /** * */ diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index 701038cb1..5cc02a91d 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -8,10 +8,11 @@ */ package org.eclipse.hawkbit.tenancy.configuration; -import org.eclipse.hawkbit.tenancy.configuration.validator.BooleanValidator; -import org.eclipse.hawkbit.tenancy.configuration.validator.PollTimeValidator; -import org.eclipse.hawkbit.tenancy.configuration.validator.StringValidator; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationPollingDurationValidator; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationStringValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidator; +import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; import org.springframework.context.ApplicationContext; /** @@ -29,32 +30,32 @@ public enum TenantConfigurationKey { */ AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", "hawkbit.server.controller.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(), - BooleanValidator.class), + TenantConfigurationBooleanValidator.class), /** * */ AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", "hawkbit.server.controller.security.authentication.header.authority", Boolean.class, - Boolean.FALSE.toString(), BooleanValidator.class), + Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class), /** * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", "hawkbit.server.controller.security.authentication.targettoken.enabled", Boolean.class, - Boolean.FALSE.toString(), BooleanValidator.class), + Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class), /** * boolean value {@code true} {@code false}. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", "hawkbit.server.controller.security.authentication.gatewaytoken.enabled", Boolean.class, - Boolean.FALSE.toString(), BooleanValidator.class), + Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class), /** * string value which holds the name of the security token key. */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", "hawkbit.server.controller.security.authentication.gatewaytoken.name", String.class, null, - StringValidator.class), + TenantConfigurationStringValidator.class), /** * string value which holds the actual security-key of the gateway security @@ -62,19 +63,19 @@ public enum TenantConfigurationKey { */ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", "hawkbit.server.controller.security.authentication.gatewaytoken.key", String.class, null, - StringValidator.class), + TenantConfigurationStringValidator.class), /** * string value which holds the polling time interval in the format HH:mm:ss */ POLLING_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null, - PollTimeValidator.class), + TenantConfigurationPollingDurationValidator.class), /** * string value which holds the polling time interval in the format HH:mm:ss */ POLLING_OVERDUE_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null, - PollTimeValidator.class); + TenantConfigurationPollingDurationValidator.class); private final String keyName; private final String defaultKeyName; @@ -127,11 +128,26 @@ public enum TenantConfigurationKey { return dataType; } - public boolean validate(final ApplicationContext context, final Object value) { + /** + * validates if a object matches the allowed data format of the + * corresponding key + * + * @param context + * application context + * @param value + * which will be validated + * @throws TenantConfigurationValidatorException + * is thrown when object is invalid. + */ + public void validate(final ApplicationContext context, final Object value) + throws TenantConfigurationValidatorException { final TenantConfigurationValidator createBean = context.getAutowireCapableBeanFactory().createBean(validator); - final boolean isValid = createBean.validate(value); - context.getAutowireCapableBeanFactory().destroyBean(createBean); - return isValid; + try { + createBean.validate(value); + } catch (final TenantConfigurationValidatorException ex) { + throw ex; + } finally { + context.getAutowireCapableBeanFactory().destroyBean(createBean); + } } - } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java deleted file mode 100644 index 208e3d01c..000000000 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/BooleanValidator.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.eclipse.hawkbit.tenancy.configuration.validator; - -public class BooleanValidator implements TenantConfigurationValidator { - - @Override - public boolean validate(final Object tenantConfigurationValue) { - if (tenantConfigurationValue instanceof Boolean) { - return true; - } - return false; - } - -} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java deleted file mode 100644 index b2a2ec00b..000000000 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/PollTimeValidator.java +++ /dev/null @@ -1,47 +0,0 @@ -package org.eclipse.hawkbit.tenancy.configuration.validator; - -import java.time.Duration; -import java.time.format.DateTimeParseException; - -import org.eclipse.hawkbit.ControllerPollProperties; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.springframework.beans.factory.annotation.Autowired; - -public class PollTimeValidator implements TenantConfigurationValidator { - - // private final ControllerPollProperties properties; - - private final DurationHelper durationHelper = new DurationHelper(); - - private final Duration minDuration; - - private final Duration maxDuration; - - @Autowired - public PollTimeValidator(final ControllerPollProperties properties) { - // this.properties = properties; - - minDuration = durationHelper.formattedStringToDuration(properties.getMinPollingTime()); - maxDuration = durationHelper.formattedStringToDuration(properties.getMaxPollingTime()); - } - - @Override - public boolean validate(final Object tenantConfigurationObject) { - if (!(tenantConfigurationObject instanceof String)) { - return false; - } - - final String tenantConfigurationString = (String) tenantConfigurationObject; - - try { - final Duration tenantConfigurationValue = durationHelper - .formattedStringToDuration(tenantConfigurationString); - - return durationHelper.durationRangeValidator(minDuration, maxDuration) - .isWithinRange(tenantConfigurationValue); - - } catch (final DateTimeParseException ex) { - return false; - } - } -} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java deleted file mode 100644 index 925d46cb9..000000000 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/StringValidator.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.eclipse.hawkbit.tenancy.configuration.validator; - -public class StringValidator implements TenantConfigurationValidator { - - @Override - public boolean validate(final Object tenantConfigurationValue) { - if (tenantConfigurationValue instanceof String) { - return true; - } - - return false; - } -} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java new file mode 100644 index 000000000..584863de6 --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java @@ -0,0 +1,18 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator; + +import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; + +/** + * specific tenant configuration validator, which validates that the given value is a booleans. + */ +public class TenantConfigurationBooleanValidator implements TenantConfigurationValidator { + + @Override + public void validate(final Object tenantConfigurationValue) { + if (tenantConfigurationValue instanceof Boolean) { + return; + } + throw new TenantConfigurationValidatorException("The given configuration value is expected as a boolean."); + } + +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java new file mode 100644 index 000000000..34c7f80a2 --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java @@ -0,0 +1,62 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator; + +import java.time.Duration; +import java.time.format.DateTimeParseException; + +import org.eclipse.hawkbit.ControllerPollProperties; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * specific tenant configuration validator, which validates that the given value + * is a String in the correct duration format.. + */ +public class TenantConfigurationPollingDurationValidator implements TenantConfigurationValidator { + + // private final ControllerPollProperties properties; + + private final DurationHelper durationHelper = new DurationHelper(); + + private final Duration minDuration; + + private final Duration maxDuration; + + /** + * @param properties + * property accessor for poll configuration + */ + @Autowired + public TenantConfigurationPollingDurationValidator(final ControllerPollProperties properties) { + // this.properties = properties; + + minDuration = durationHelper.formattedStringToDuration(properties.getMinPollingTime()); + maxDuration = durationHelper.formattedStringToDuration(properties.getMaxPollingTime()); + } + + @Override + public void validate(final Object tenantConfigurationObject) { + if (!(tenantConfigurationObject instanceof String)) { + throw new TenantConfigurationValidatorException("The given configuration value is expected as a string."); + } + + final String tenantConfigurationString = (String) tenantConfigurationObject; + + final Duration tenantConfigurationValue; + try { + tenantConfigurationValue = durationHelper.formattedStringToDuration(tenantConfigurationString); + + } catch (final DateTimeParseException ex) { + throw new TenantConfigurationValidatorException( + String.format("The given configuration value is expected as a string in the format %s.", + DurationHelper.DURATION_FORMAT)); + } + + if (!durationHelper.durationRangeValidator(minDuration, maxDuration).isWithinRange(tenantConfigurationValue)) { + throw new TenantConfigurationValidatorException( + String.format("The given configuration value is not in the allowed range from %s to %s.", + durationHelper.durationToFormattedString(minDuration), + durationHelper.durationToFormattedString(maxDuration))); + } + } +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java new file mode 100644 index 000000000..fd4ccf50b --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java @@ -0,0 +1,17 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator; + +import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; + +/** + * specific tenant configuration validator, which validates Strings. + */ +public class TenantConfigurationStringValidator implements TenantConfigurationValidator { + + @Override + public void validate(final Object tenantConfigurationValue) { + if (tenantConfigurationValue instanceof String) { + return; + } + throw new TenantConfigurationValidatorException("The given configuration value is expected as a String."); + } +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java index 3d2f0b1c7..49a167f32 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java @@ -1,6 +1,20 @@ package org.eclipse.hawkbit.tenancy.configuration.validator; +import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; + +/** + * base interface for clases which can validate tenant configuration values. + * + */ public interface TenantConfigurationValidator { - boolean validate(Object tenantConfigurationValue); + /** + * validates the tenant configuration value + * + * @param tenantConfigurationValue + * value which will be validated. + * @throws TenantConfigurationValidatorException + * is thrown, when parameter is invalid. + */ + void validate(Object tenantConfigurationValue) throws TenantConfigurationValidatorException; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/exceptions/TenantConfigurationValidatorException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/exceptions/TenantConfigurationValidatorException.java new file mode 100644 index 000000000..a9afc1d88 --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/exceptions/TenantConfigurationValidatorException.java @@ -0,0 +1,55 @@ +package org.eclipse.hawkbit.tenancy.configuration.validator.exceptions; + +import org.eclipse.hawkbit.exception.SpServerError; +import org.eclipse.hawkbit.exception.SpServerRtException; + +/** + * Exception which is thrown, when the validation of the configuration value has + * not been successful. + * + */ +public class TenantConfigurationValidatorException extends SpServerRtException { + + private static final long serialVersionUID = 1L; + private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_VALUE_INVALID; + + /** + * Default constructor. + */ + public TenantConfigurationValidatorException() { + super(THIS_ERROR); + } + + /** + * Parameterized constructor. + * + * @param cause + * of the exception + */ + public TenantConfigurationValidatorException(final Throwable cause) { + super(THIS_ERROR, cause); + } + + /** + * Parameterized constructor. + * + * @param message + * of the exception + * @param cause + * of the exception + */ + public TenantConfigurationValidatorException(final String message, final Throwable cause) { + super(message, THIS_ERROR, cause); + } + + /** + * Parameterized constructor. + * + * @param message + * of the exception + */ + public TenantConfigurationValidatorException(final String message) { + super(message, THIS_ERROR); + } + +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java index f054e4bc5..bb938a780 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java @@ -65,6 +65,7 @@ public class ResponseExceptionHandler { ERROR_TO_HTTP_STATUS.put(SpServerError.SP_REPO_TENANT_NOT_EXISTS, HttpStatus.BAD_REQUEST); ERROR_TO_HTTP_STATUS.put(SpServerError.SP_ENTITY_LOCKED, HttpStatus.LOCKED); 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); } private static HttpStatus getStatusOrDefault(final SpServerError error) { From 4be880587a2db1bcb3c804617ebf3ccbfe8bc624 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 28 Jan 2016 18:16:31 +0100 Subject: [PATCH 19/42] Added validation before saving TenantConfiguration and updated tests * run the validation methodes inside the storing methode, to make sure that only valid values are written inside the database * updated TenantConfigurationManagementTest to match the validation * added new Tests to test all validators Signed-off-by: Nonnenmacher Fabian --- .../configuration/TenantConfigurationKey.java | 11 +- .../TenantConfigurationManagement.java | 33 ++-- .../TenantConfigurationManagementTest.java | 164 ++++++++++++++---- .../resources/application-test.properties | 1 + .../resource/SystemManagementResource.java | 17 +- .../PollingConfigurationView.java | 11 +- ...ficateAuthenticationConfigurationItem.java | 8 +- ...yTokenAuthenticationConfigurationItem.java | 18 +- ...yTokenAuthenticationConfigurationItem.java | 4 +- 9 files changed, 193 insertions(+), 74 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index 5cc02a91d..632b77b87 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.tenancy.configuration; +import java.util.Arrays; + import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationPollingDurationValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationStringValidator; @@ -19,9 +21,6 @@ import org.springframework.context.ApplicationContext; * An enum which defines the tenant specific configurations which can be * configured for each tenant seperately. * - * - * - * */ public enum TenantConfigurationKey { @@ -150,4 +149,10 @@ public enum TenantConfigurationKey { context.getAutowireCapableBeanFactory().destroyBean(createBean); } } + + public static TenantConfigurationKey fromKeyName(final String keyName) { + + return Arrays.stream(TenantConfigurationKey.values()).filter(conf -> conf.getKeyName().equals(keyName)) + .findFirst().get(); + } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 75210d9ef..0837a8d24 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -1,13 +1,12 @@ package org.eclipse.hawkbit.repository; -import java.util.List; - import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.ApplicationContext; import org.springframework.context.EnvironmentAware; import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.support.ConfigurableConversionService; @@ -26,6 +25,9 @@ public class TenantConfigurationManagement implements EnvironmentAware { @Autowired private TenantConfigurationRepository tenantConfigurationRepository; + @Autowired + private ApplicationContext applicationContext; + private final ConfigurableConversionService conversionService = new DefaultConversionService(); private Environment environment; @@ -58,6 +60,11 @@ public class TenantConfigurationManagement implements EnvironmentAware { public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) { + if (configurationKey.getDataType() != propertyType) { + throw new IllegalAccessError(String.format("The key %s does not handle values in the type %s.", + configurationKey.getKeyName(), propertyType)); + } + final TenantConfiguration tenantConfiguration = tenantConfigurationRepository .findByKey(configurationKey.getKeyName()); @@ -90,14 +97,17 @@ public class TenantConfigurationManagement implements EnvironmentAware { @CacheEvict(value = "tenantConfiguration", key = "#tenantConf.getKey()") @Transactional @Modifying - public TenantConfiguration addOrUpdateConfiguration(final TenantConfiguration tenantConf) { - TenantConfiguration tenantConfiguration = tenantConfigurationRepository.findByKey(tenantConf.getKey()); + public void addOrUpdateConfiguration(final TenantConfigurationKey tenantConfkey, final Object value) { + + tenantConfkey.validate(applicationContext, value); + + TenantConfiguration tenantConfiguration = tenantConfigurationRepository.findByKey(tenantConfkey.getKeyName()); if (tenantConfiguration != null) { - tenantConfiguration.setValue(tenantConf.getValue()); + tenantConfiguration.setValue(value.toString()); } else { - tenantConfiguration = new TenantConfiguration(tenantConf.getKey(), tenantConf.getValue()); + tenantConfiguration = new TenantConfiguration(tenantConfkey.getKeyName(), value.toString()); } - return tenantConfigurationRepository.save(tenantConfiguration); + tenantConfigurationRepository.save(tenantConfiguration); } /** @@ -113,10 +123,11 @@ public class TenantConfigurationManagement implements EnvironmentAware { tenantConfigurationRepository.deleteByKey(configurationKey.getKeyName()); } - @Transactional - public List getTenantConfigurations() { - return tenantConfigurationRepository.findAll(); - } + // @Transactional + // public List getTenantConfigurations() { + // + // return tenantConfigurationRepository.findAll(); + // } @Override public void setEnvironment(final Environment environment) { diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java index 73130407e..67f6915e1 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java @@ -2,11 +2,17 @@ package org.eclipse.hawkbit.repository; import static org.fest.assertions.api.Assertions.assertThat; +import java.time.Duration; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB; -import org.eclipse.hawkbit.repository.model.TenantConfiguration; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; import org.junit.Test; -import org.springframework.core.convert.ConversionFailedException; import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; @@ -16,70 +22,75 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("Tenant Configuration Management") public class TenantConfigurationManagementTest extends AbstractIntegrationTestWithMongoDB { + final DurationHelper durationHelper = new DurationHelper(); + @Test @Description("Tests that tenant specific configuration can be persisted and in case the tenant does not have specific configuration the default from environment is used instead.") - public void storeTenantSpecificConfiguration() { - final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; + public void storeTenantSpecificConfigurationAsString() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME; final String envPropertyDefault = environment.getProperty(configKey.getDefaultKeyName()); assertThat(envPropertyDefault).isNotNull(); // get the configuration from the system management - final String defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class) - .getValue(); - assertThat(envPropertyDefault).isEqualTo(defaultConfigValue); + final TenantConfigurationValue defaultConfigValue = tenantConfigurationManagement + .getConfigurationValue(configKey, String.class); + + assertThat(defaultConfigValue.isGlobal()).isEqualTo(true); + assertThat(defaultConfigValue.getValue()).isEqualTo(envPropertyDefault); // update the tenant specific configuration - final String newConfigurationValue = "thisIsAnotherValueForPolling"; - assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue); - tenantConfigurationManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); + final String newConfigurationValue = "thisIsAnotherTokenName"; + assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue.getValue()); + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, newConfigurationValue); // verify that new configuration value is used - final String updatedConfigurationValue = tenantConfigurationManagement - .getConfigurationValue(configKey, String.class).getValue(); - assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); - assertThat(tenantConfigurationManagement.getTenantConfigurations()).hasSize(1); + final TenantConfigurationValue updatedConfigurationValue = tenantConfigurationManagement + .getConfigurationValue(configKey, String.class); + + assertThat(updatedConfigurationValue.isGlobal()).isEqualTo(false); + assertThat(updatedConfigurationValue.getValue()).isEqualTo(newConfigurationValue); + // assertThat(tenantConfigurationManagement.getTenantConfigurations()).hasSize(1); } @Test @Description("Tests that the tenant specific configuration can be updated") public void updateTenantSpecifcConfiguration() { - final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME; final String value1 = "firstValue"; final String value2 = "secondValue"; // add value first - tenantConfigurationManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value1)); + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1); assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()) .isEqualTo(value1); // update to value second - tenantConfigurationManagement.addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), value2)); + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2); assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()) .isEqualTo(value2); } @Test @Description("Tests that the configuration value can be converted from String to Integer automatically") - public void tenantConfigurationValueConversion() { + public void storeAndUpdateTenantSpecificConfigurationAsBoolean() { final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; - final Integer value1 = 123; - tenantConfigurationManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), String.valueOf(value1))); - assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Integer.class).getValue()) + final Boolean value1 = true; + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1); + assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue()) .isEqualTo(value1); + final Boolean value2 = false; + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2); + assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue()) + .isEqualTo(value2); } - @Test(expected = ConversionFailedException.class) - @Description("Tests that the get configuration throws exception in case the value cannot be automatically converted from String to Integer") - public void wrongTenantConfigurationValueConversionThrowsException() { + @Test(expected = TenantConfigurationValidatorException.class) + @Description("Tests that the get configuration throws exception in case the value cannot be automatically converted from String to Boolean") + public void wrongTenantConfigurationValueTypeThrowsException() { final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; - final String value1 = "thisIsNotANumber"; + final String value1 = "thisIsNotABoolean"; // add value as String - tenantConfigurationManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), String.valueOf(value1))); - // try to get it as Integer - tenantConfigurationManagement.getConfigurationValue(configKey, Integer.class); + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1); } @Test @@ -96,8 +107,7 @@ public class TenantConfigurationManagementTest extends AbstractIntegrationTestWi // update the tenant specific configuration final String newConfigurationValue = "thisIsAnotherValueForPolling"; assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue); - tenantConfigurationManagement - .addOrUpdateConfiguration(new TenantConfiguration(configKey.getKeyName(), newConfigurationValue)); + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, newConfigurationValue); // verify that new configuration value is used final String updatedConfigurationValue = tenantConfigurationManagement @@ -110,4 +120,92 @@ public class TenantConfigurationManagementTest extends AbstractIntegrationTestWi // must be null now assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isNull(); } + + @Test(expected = TenantConfigurationValidatorException.class) + @Description("Test that an Exception is thrown, when an integer is stored but a string expected.") + public void storesIntegerWhenStringIsExpected() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME; + final Integer wrongDataype = 123; + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataype); + } + + @Test(expected = TenantConfigurationValidatorException.class) + @Description("Test that an Exception is thrown, when an integer is stored but a boolean expected.") + public void storesIntegerWhenBooleanIsExpected() { + final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED; + final Integer wrongDataype = 123; + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataype); + } + + @Test(expected = TenantConfigurationValidatorException.class) + @Description("Test that an Exception is thrown, when an integer is stored as PollingTime.") + public void storesIntegerWhenPollingIntervalIsExpected() { + final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL; + final Integer wrongDataype = 123; + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataype); + } + + @Test(expected = TenantConfigurationValidatorException.class) + @Description("Test that an Exception is thrown, when an invalid formatted string is stored as PollingTime.") + public void storesWrongFormattedStringAsPollingInterval() { + final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL; + final String wrongFormatted = "wrongFormatted"; + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongFormatted); + } + + @Test(expected = TenantConfigurationValidatorException.class) + @Description("Test that an Exception is thrown, when an invalid formatted string is stored as PollingTime.") + public void storesTooSmallDurationAsPollingInterval() { + final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL; + + final String tooSmallDuration = durationHelper + .durationToFormattedString(durationHelper.getDurationByTimeValues(0, 0, 1)); + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, tooSmallDuration); + } + + @Test + @Description("Stores a correct formatted PollignTime and reads it again.") + public void storesCorrectDurationAsPollingInterval() { + final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL; + + final Duration duration = durationHelper.getDurationByTimeValues(1, 2, 0); + assertThat(duration).isEqualTo(Duration.ofHours(1).plusMinutes(2)); + + tenantConfigurationManagement.addOrUpdateConfiguration(configKey, + durationHelper.durationToFormattedString(duration)); + + final String storedDurationString = tenantConfigurationManagement.getConfigurationValue(configKey, String.class) + .getValue(); + assertThat(duration).isEqualTo(durationHelper.formattedStringToDuration(storedDurationString)); + } + + @Test(expected = IllegalAccessError.class) + @Description("Request a config value in a wrong Value") + public void requestConfigValueWithWrongType() { + tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, Object.class); + } + + @Test + @Description("Verifies that every TenenatConfiguraationKeyName exists only once") + public void verifyThatAllKeysAreDifferent() { + final Map keynames = new HashMap(); + + Arrays.stream(TenantConfigurationKey.values()).forEach(key -> { + + if (keynames.containsKey(key.getKeyName())) { + throw new IllegalStateException("The key names are not unique"); + } + + keynames.put(key.getKeyName(), null); + }); + } + + @Test + @Description("Get TenantConfigurationKeyByName") + public void getTenantConfigurationKeyByName() { + final TenantConfigurationKey configKey = TenantConfigurationKey.POLLING_TIME_INTERVAL; + + assertThat(TenantConfigurationKey.fromKeyName(configKey.getKeyName())).isEqualTo(configKey); + } + } diff --git a/hawkbit-repository/src/test/resources/application-test.properties b/hawkbit-repository/src/test/resources/application-test.properties index e5fb04a21..8e8169a64 100644 --- a/hawkbit-repository/src/test/resources/application-test.properties +++ b/hawkbit-repository/src/test/resources/application-test.properties @@ -11,6 +11,7 @@ spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value} spring.data.mongodb.port=28017 hawkbit.server.controller.security.authentication.header.enabled=true +hawkbit.server.controller.security.authentication.gatewaytoken.name=TestToken hawkbit.server.artifact.repo.upload.maxFileSize=5MB diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java index b533ff96a..0a430223c 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java @@ -18,11 +18,11 @@ import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.report.model.TenantUsage; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.rest.resource.model.system.CacheRest; import org.eclipse.hawkbit.rest.resource.model.system.SystemStatisticsRest; import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationRest; import org.eclipse.hawkbit.rest.resource.model.system.TenantSystemUsageRest; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -147,7 +147,20 @@ public class SystemManagementResource { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) public ResponseEntity addUpdateConfig(@RequestBody final TenantConfigurationRest configuration, @PathVariable final String key) { - tenantConfigurationManagement.addOrUpdateConfiguration(new TenantConfiguration(key, configuration.getValue())); + + // TODO Quick and dirty to stay compatible, but these rest interface + // won't be necessary in future + + Object value; + if (configuration.getValue().equals(Boolean.TRUE)) { + value = true; + } else if (configuration.getValue().equals(Boolean.FALSE)) { + value = false; + } else { + value = configuration.getValue(); + } + + tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.fromKeyName(key), value); return ResponseEntity.ok().build(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 3e3c84fcc..016e5eb6d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -6,7 +6,6 @@ import javax.annotation.PostConstruct; import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; @@ -111,16 +110,14 @@ public class PollingConfigurationView extends BaseConfigurationView if (!compareDurations(tenantPollTime, fieldPollTime.getValue())) { tenantPollTime = fieldPollTime.getValue(); - tenantConfigurationManagement.addOrUpdateConfiguration( - new TenantConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL.getKeyName(), - durationHelper.durationToFormattedString(tenantPollTime))); + tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, + durationHelper.durationToFormattedString(tenantPollTime)); } if (!compareDurations(tenantOverdueTime, fieldPollingOverdueTime.getValue())) { tenantOverdueTime = fieldPollingOverdueTime.getValue(); - tenantConfigurationManagement.addOrUpdateConfiguration( - new TenantConfiguration(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL.getKeyName(), - durationHelper.durationToFormattedString(tenantOverdueTime))); + tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, + durationHelper.durationToFormattedString(tenantOverdueTime)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java index 0263b202e..cf2744718 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/CertificateAuthenticationConfigurationItem.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.utils.I18N; @@ -134,13 +133,12 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti @Override public void save() { if (configurationEnabledChange) { - getTenantConfigurationManagement().addOrUpdateConfiguration( - new TenantConfiguration(getConfigurationKey().getKeyName(), String.valueOf(configurationEnabled))); + getTenantConfigurationManagement().addOrUpdateConfiguration(getConfigurationKey(), configurationEnabled); } if (configurationCaRootAuthorityChanged) { final String value = caRootAuthorityTextField.getValue() != null ? caRootAuthorityTextField.getValue() : ""; - getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( - TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME.getKeyName(), value)); + getTenantConfigurationManagement() + .addOrUpdateConfiguration(TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, value); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java index 556d4e08c..12bfae7c6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; @@ -189,20 +188,19 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac @Override public void save() { if (configurationEnabledChange) { - getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( - TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED.getKeyName(), - String.valueOf(configurationEnabled))); + getTenantConfigurationManagement().addOrUpdateConfiguration( + TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED, configurationEnabled); } if (keyNameChanged) { - getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( - TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME.getKeyName(), - gatewayTokenNameTextField.getValue())); + getTenantConfigurationManagement().addOrUpdateConfiguration( + TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME, + gatewayTokenNameTextField.getValue()); } if (keyChanged) { - getTenantConfigurationManagement().addOrUpdateConfiguration(new TenantConfiguration( - TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY.getKeyName(), - gatewayTokenkeyLabel.getValue())); + getTenantConfigurationManagement().addOrUpdateConfiguration( + TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, + gatewayTokenkeyLabel.getValue()); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java index 4e9bd0572..616e64769 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.ui.tenantconfiguration.authentication; import javax.annotation.PostConstruct; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.ui.utils.I18N; import org.springframework.beans.factory.annotation.Autowired; @@ -89,8 +88,7 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract @Override public void save() { if (configurationEnabledChange) { - getTenantConfigurationManagement().addOrUpdateConfiguration( - new TenantConfiguration(getConfigurationKey().getKeyName(), String.valueOf(configurationEnabled))); + getTenantConfigurationManagement().addOrUpdateConfiguration(getConfigurationKey(), configurationEnabled); } } From ec79e9bd195cde79313e4ec3b84d82c5613d6374 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 28 Jan 2016 18:44:31 +0100 Subject: [PATCH 20/42] Added REST interfaces for tenant configuration - added GET, DELETE and PUT function on configuration value interfaces - changed Exception in TenantConfigurationManagement for correct mapping to HTTP Status - added function to get global configurations from TenantConfigurationManagement, to have only one class for handling these configuration values Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/exception/SpServerError.java | 6 +- .../exception/SpServerRtException.java | 4 + ...nvalidTenantConfigurationKeyException.java | 55 ++++++ .../configuration/TenantConfigurationKey.java | 24 ++- .../TenantConfigurationBooleanValidator.java | 2 - ...ConfigurationPollingDurationValidator.java | 1 - .../TenantConfigurationStringValidator.java | 2 - .../TenantConfigurationValidator.java | 2 - ...TenantConfigurationValidatorException.java | 2 +- .../TenantConfigurationManagement.java | 170 ++++++++++++++---- .../TenantConfigurationManagementTest.java | 16 +- .../SystemConfigurationRequestBodyPut.java | 105 ----------- .../model/system/SystemConfigurationRest.java | 40 ----- .../model/system/TenantConfigurationRest.java | 6 +- .../TenantConfigurationValueRequest.java | 35 ++++ .../resource/ResponseExceptionHandler.java | 1 + .../resource/SystemManagementResource.java | 4 +- .../hawkbit/rest/resource/SystemMapper.java | 57 +++--- .../hawkbit/rest/resource/SystemResource.java | 97 ++++++++-- .../PollingConfigurationView.java | 6 +- 20 files changed, 389 insertions(+), 246 deletions(-) create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java rename hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/{exceptions => }/TenantConfigurationValidatorException.java (95%) delete mode 100644 hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java delete mode 100644 hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java create mode 100644 hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.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 068edf80c..c7eb2b159 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 @@ -181,7 +181,11 @@ public enum SpServerError { * */ SP_CONFIGURATION_VALUE_INVALID("hawkbit.server.error.configValueInvalid", - "The given configuration value is invalid."); + "The given configuration value is invalid."), + /** + * + */ + SP_CONFIGURATION_KEY_INVALID("hawkbit.server.error.configKeyInvalid", "The given configuration key is invalid."); /** * diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java index a605f7745..46ee644ce 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java @@ -74,6 +74,10 @@ public abstract class SpServerRtException extends RuntimeException { this.error = error; } + /** + * + * @return the SpServerError + */ public SpServerError getError() { return error; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java new file mode 100644 index 000000000..49edd231c --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java @@ -0,0 +1,55 @@ +package org.eclipse.hawkbit.tenancy.configuration; + +import org.eclipse.hawkbit.exception.SpServerError; +import org.eclipse.hawkbit.exception.SpServerRtException; + +/** + * The {@link #InvalidTenantConfigurationKeyException} is thrown when an invalid + * configuration key is used. + * + */ +public class InvalidTenantConfigurationKeyException extends SpServerRtException { + + private static final long serialVersionUID = 1L; + private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_KEY_INVALID; + + /** + * Default constructor. + */ + public InvalidTenantConfigurationKeyException() { + super(THIS_ERROR); + } + + /** + * Parameterized constructor. + * + * @param cause + * of the exception + */ + public InvalidTenantConfigurationKeyException(final Throwable cause) { + super(THIS_ERROR, cause); + } + + /** + * Parameterized constructor. + * + * @param message + * of the exception + * @param cause + * of the exception + */ + public InvalidTenantConfigurationKeyException(final String message, final Throwable cause) { + super(message, THIS_ERROR, cause); + } + + /** + * Parameterized constructor. + * + * @param message + * of the exception + */ + public InvalidTenantConfigurationKeyException(final String message) { + super(message, THIS_ERROR); + } + +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index 632b77b87..fc1e3a856 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -9,12 +9,13 @@ package org.eclipse.hawkbit.tenancy.configuration; import java.util.Arrays; +import java.util.NoSuchElementException; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationPollingDurationValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationStringValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidator; -import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException; import org.springframework.context.ApplicationContext; /** @@ -121,7 +122,8 @@ public enum TenantConfigurationKey { /** * - * @return the datatype of the tenant configuration value + * @return the data type of the tenant configuration value. (e.g. + * Integer.class, String.class) */ public Class getDataType() { return dataType; @@ -150,9 +152,21 @@ public enum TenantConfigurationKey { } } - public static TenantConfigurationKey fromKeyName(final String keyName) { + /** + * @param keyName + * name of the TenantConfigurationKey + * @return the TenantConfigurationKey with the name keyName + * @throws InvalidTenantConfigurationKeyException + * if there is no TenantConfigurationKey with the name keyName + */ + public static TenantConfigurationKey fromKeyName(final String keyName) + throws InvalidTenantConfigurationKeyException { - return Arrays.stream(TenantConfigurationKey.values()).filter(conf -> conf.getKeyName().equals(keyName)) - .findFirst().get(); + try { + return Arrays.stream(TenantConfigurationKey.values()).filter(conf -> conf.getKeyName().equals(keyName)) + .findFirst().get(); + } catch (final NoSuchElementException e) { + throw new InvalidTenantConfigurationKeyException("The given configuration key name does not exist."); + } } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java index 584863de6..0a8840933 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java @@ -1,7 +1,5 @@ package org.eclipse.hawkbit.tenancy.configuration.validator; -import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; - /** * specific tenant configuration validator, which validates that the given value is a booleans. */ diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java index 34c7f80a2..2dfd9b6c2 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java @@ -5,7 +5,6 @@ import java.time.format.DateTimeParseException; import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; import org.springframework.beans.factory.annotation.Autowired; /** diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java index fd4ccf50b..c71744773 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java @@ -1,7 +1,5 @@ package org.eclipse.hawkbit.tenancy.configuration.validator; -import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; - /** * specific tenant configuration validator, which validates Strings. */ diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java index 49a167f32..83a8686c4 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java @@ -1,7 +1,5 @@ package org.eclipse.hawkbit.tenancy.configuration.validator; -import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; - /** * base interface for clases which can validate tenant configuration values. * diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/exceptions/TenantConfigurationValidatorException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java similarity index 95% rename from hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/exceptions/TenantConfigurationValidatorException.java rename to hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java index a9afc1d88..4ce509a46 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/exceptions/TenantConfigurationValidatorException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java @@ -1,4 +1,4 @@ -package org.eclipse.hawkbit.tenancy.configuration.validator.exceptions; +package org.eclipse.hawkbit.tenancy.configuration.validator; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerRtException; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 0837a8d24..74c864748 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -3,6 +3,7 @@ package org.eclipse.hawkbit.repository; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; @@ -16,6 +17,9 @@ import org.springframework.data.jpa.repository.Modifying; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +/** + * Central tenant configuration management operations of the SP server. + */ @Transactional(readOnly = true) @Validated public class TenantConfigurationManagement implements EnvironmentAware { @@ -32,6 +36,12 @@ public class TenantConfigurationManagement implements EnvironmentAware { private Environment environment; + /** + * Get Singleton instance, needed for classes which are not managed in + * Spring context + * + * @return singleton instance of TenantConfigurationManagement + */ public static TenantConfigurationManagement getInstance() { return INSTANCE; } @@ -42,7 +52,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { * configuration the global default value hold in the {@link Environment}. * * @param - * + * the type of the configuration value * @param configurationKey * the key of the configuration * @param propertyType @@ -52,17 +62,21 @@ public class TenantConfigurationManagement implements EnvironmentAware { * configuration stored or from the fallback default values or * {@code null} in case key has not been configured and not default * value exists + * @throws TenantConfigurationValidatorException + * if the {@code propertyType} and the value in general does not + * match the expected type and format defined by the Key * @throws ConversionFailedException * if the property cannot be converted to the given * {@code propertyType} */ @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, - final Class propertyType) { + final Class propertyType) throws TenantConfigurationValidatorException { - if (configurationKey.getDataType() != propertyType) { - throw new IllegalAccessError(String.format("The key %s does not handle values in the type %s.", - configurationKey.getKeyName(), propertyType)); + if (!configurationKey.getDataType().isAssignableFrom(propertyType)) { + throw new TenantConfigurationValidatorException( + String.format("Cannot parse the database value of type %s into the type %s.", + configurationKey.getDataType(), propertyType)); } final TenantConfiguration tenantConfiguration = tenantConfigurationRepository @@ -76,42 +90,132 @@ public class TenantConfigurationManagement implements EnvironmentAware { .value(conversionService.convert(tenantConfiguration.getValue(), propertyType)).build(); } else if (configurationKey.getDefaultKeyName() != null) { - final T valueInProperties = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType); return TenantConfigurationValue. builder().isGlobal(true).createdBy(null).createdAt(null) - .lastModifiedAt(null).lastModifiedBy(null).value(valueInProperties != null ? valueInProperties - : conversionService.convert(configurationKey.getDefaultValue(), propertyType)) - .build(); + .lastModifiedAt(null).lastModifiedBy(null) + .value(getGlobalConfigurationValue(configurationKey, propertyType)).build(); } return null; } /** - * Adds or updates a specific configuration for a specific tenant. - * - * @param tenantConf - * the tenant configuration object which contains the key and - * value of the specific configuration to update - * @return the added or updated TenantConfiguration + * Retrieves a configuration value from the e.g. tenant overwritten + * configuration values or in case the tenant does not a have a specific + * configuration the global default value hold in the {@link Environment}. + * + * @param configurationKey + * the key of the configuration + * @return the converted configuration value either from the tenant specific + * configuration stored or from the fallback default values or + * {@code null} in case key has not been configured and not default + * value exists + * @throws TenantConfigurationValidatorException + * if the {@code propertyType} and the value in general does not + * match the expected type and format defined by the Key + * @throws ConversionFailedException + * if the property cannot be converted to the given + * {@code propertyType} */ - @CacheEvict(value = "tenantConfiguration", key = "#tenantConf.getKey()") - @Transactional - @Modifying - public void addOrUpdateConfiguration(final TenantConfigurationKey tenantConfkey, final Object value) { - - tenantConfkey.validate(applicationContext, value); - - TenantConfiguration tenantConfiguration = tenantConfigurationRepository.findByKey(tenantConfkey.getKeyName()); - if (tenantConfiguration != null) { - tenantConfiguration.setValue(value.toString()); - } else { - tenantConfiguration = new TenantConfiguration(tenantConfkey.getKeyName(), value.toString()); - } - tenantConfigurationRepository.save(tenantConfiguration); + public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey) + throws TenantConfigurationValidatorException { + return getConfigurationValue(configurationKey, configurationKey.getDataType()); } /** - * Deletes a specific configuration for the current tenant. + * returns the global configuration property either defined in the property + * file or an default value otherwise. + * + * @param + * the type of the configuration value + * @param configurationKey + * the key of the configuration + * @param propertyType + * the type of the configuration value, e.g. {@code String.class} + * , {@code Integer.class}, etc + * @return the global configured value + * @throws TenantConfigurationValidatorException + * if the {@code propertyType} and the value in the property + * file or the default value does not match the expected type + * and format defined by the Key + * @throws ConversionFailedException + * if the property cannot be converted to the given + * {@code propertyType} + */ + @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") + public T getGlobalConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) + throws TenantConfigurationValidatorException { + + if (!configurationKey.getDataType().isAssignableFrom(propertyType)) { + throw new TenantConfigurationValidatorException( + String.format("Cannot parse the database value of type %s into the type %s.", + configurationKey.getDataType(), propertyType)); + } + + final T valueInProperties = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType); + + if (valueInProperties != null) { + return valueInProperties; + } + return conversionService.convert(configurationKey.getDefaultValue(), propertyType); + } + + /** + * Adds or updates a specific configuration for a specific tenant. + * + * + * @param configurationKey + * the key of the configuration + * @param value + * the configuration value which will be written into the + * database. + * @return the configuration value which was just written into the database. + * @throws TenantConfigurationValidatorException + * if the {@code propertyType} and the value in general does not + * match the expected type and format defined by the Key + * @throws ConversionFailedException + * if the property cannot be converted to the given + */ + @CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") + @Transactional + @Modifying + public TenantConfigurationValue addOrUpdateConfiguration(final TenantConfigurationKey configurationKey, + final T value) { + + if (!configurationKey.getDataType().isAssignableFrom(value.getClass())) { + throw new TenantConfigurationValidatorException(String.format( + "Cannot parse the value %s of type %s into the type %s defined by the configuration key.", value, + value.getClass(), configurationKey.getDataType())); + } + + configurationKey.validate(applicationContext, value); + + TenantConfiguration tenantConfiguration = tenantConfigurationRepository + .findByKey(configurationKey.getKeyName()); + if (tenantConfiguration != null) + + { + tenantConfiguration.setValue(value.toString()); + } else + + { + tenantConfiguration = new TenantConfiguration(configurationKey.getKeyName(), value.toString()); + } + + final TenantConfiguration updatedTenantConfiguration = tenantConfigurationRepository.save(tenantConfiguration); + + final Class clazzT = (Class) value.getClass(); + + return TenantConfigurationValue. builder().isGlobal(false) + .createdBy(updatedTenantConfiguration.getCreatedBy()) + .createdAt(updatedTenantConfiguration.getCreatedAt()) + .lastModifiedAt(updatedTenantConfiguration.getLastModifiedAt()) + .lastModifiedBy(updatedTenantConfiguration.getLastModifiedBy()) + .value(conversionService.convert(updatedTenantConfiguration.getValue(), clazzT)).build(); + } + + /** + * Deletes a specific configuration for the current tenant. Does nothing in + * case there is no tenant specific configuration value. * * @param configurationKey * the configuration key to be deleted @@ -123,12 +227,6 @@ public class TenantConfigurationManagement implements EnvironmentAware { tenantConfigurationRepository.deleteByKey(configurationKey.getKeyName()); } - // @Transactional - // public List getTenantConfigurations() { - // - // return tenantConfigurationRepository.findAll(); - // } - @Override public void setEnvironment(final Environment environment) { this.environment = environment; diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java index 67f6915e1..6b267aa24 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java @@ -11,8 +11,10 @@ import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.eclipse.hawkbit.tenancy.configuration.validator.exceptions.TenantConfigurationValidatorException; +import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException; +import org.junit.Assert; import org.junit.Test; +import org.springframework.core.convert.ConversionFailedException; import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; @@ -84,7 +86,7 @@ public class TenantConfigurationManagementTest extends AbstractIntegrationTestWi .isEqualTo(value2); } - @Test(expected = TenantConfigurationValidatorException.class) + @Test(expected = ConversionFailedException.class) @Description("Tests that the get configuration throws exception in case the value cannot be automatically converted from String to Boolean") public void wrongTenantConfigurationValueTypeThrowsException() { final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; @@ -179,10 +181,16 @@ public class TenantConfigurationManagementTest extends AbstractIntegrationTestWi assertThat(duration).isEqualTo(durationHelper.formattedStringToDuration(storedDurationString)); } - @Test(expected = IllegalAccessError.class) + @Test @Description("Request a config value in a wrong Value") public void requestConfigValueWithWrongType() { - tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, Object.class); + try { + tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, + Object.class); + Assert.fail(""); + } catch (final TenantConfigurationValidatorException e) { + + } } @Test diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java deleted file mode 100644 index c5a3c219a..000000000 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRequestBodyPut.java +++ /dev/null @@ -1,105 +0,0 @@ -package org.eclipse.hawkbit.rest.resource.model.system; - -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * A json annotated rest model for System Configuration for PUT. - */ -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class SystemConfigurationRequestBodyPut { - - @JsonProperty - private String pollingTime; - - @JsonProperty - private String pollingOverdueTime; - - @JsonProperty - private String defaultDistributionSetType; - - @JsonProperty - private Map authenticationConfiguration; - - /** - * Gets the polling time. - * - * @return the polling time - */ - public String getPollingTime() { - return pollingTime; - } - - /** - * Sets the polling time. - * - * @param pollingTime - * the new polling time - */ - public void setPollingTime(String pollingTime) { - this.pollingTime = pollingTime; - } - - /** - * Gets the polling overdue time. - * - * @return the polling overdue time - */ - public String getPollingOverdueTime() { - return pollingOverdueTime; - } - - /** - * Sets the polling overdue time. - * - * @param pollingOverdueTime - * the new polling overdue time - */ - public void setPollingOverdueTime(String pollingOverdueTime) { - this.pollingOverdueTime = pollingOverdueTime; - } - - /** - * Gets the default distribution set type. - * - * @return the default distribution set type - */ - public String getDefaultDistributionSetType() { - return defaultDistributionSetType; - } - - /** - * Sets the default distribution set type. - * - * @param defaultDistributionSetType - * the new default distribution set type - */ - public void setDefaultDistributionSetType(String defaultDistributionSetType) { - this.defaultDistributionSetType = defaultDistributionSetType; - } - - /** - * Gets the authentication configuration. - * - * @return the authentication configuration - */ - public Map getAuthenticationConfiguration() { - return authenticationConfiguration; - } - - /** - * Sets the authentication configuration. - * - * @param authenticationConfiguration - * the authentication configuration - */ - public void setAuthenticationConfiguration(Map authenticationConfiguration) { - this.authenticationConfiguration = authenticationConfiguration; - } - -} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java deleted file mode 100644 index 7416e55cc..000000000 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemConfigurationRest.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.eclipse.hawkbit.rest.resource.model.system; - -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * A json annotated rest model for SysteConfiguration to RESTful API - * representation. - * - */ -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class SystemConfigurationRest { - - @JsonProperty - private Map configuration; - - /** - * Sets the authentication configuration. - * - * @param configuration - * the authentication configuration - */ - public void setConfiguration(final Map configuration) { - this.configuration = configuration; - } - - /** - * Gets the authentication configuration. - * - * @return the authentication configuration - */ - public Map getConfiguration() { - return this.configuration; - } -} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java index 2d31d9f61..0c8a8e54d 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; public class TenantConfigurationRest { private String key; - private String value; + private Object value; /** * @return the key @@ -41,7 +41,7 @@ public class TenantConfigurationRest { /** * @return the value */ - public String getValue() { + public Object getValue() { return value; } @@ -49,7 +49,7 @@ public class TenantConfigurationRest { * @param value * the value to set */ - public void setValue(final String value) { + public void setValue(final Object value) { this.value = value; } } diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java new file mode 100644 index 000000000..f6be11c51 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java @@ -0,0 +1,35 @@ +package org.eclipse.hawkbit.rest.resource.model.system; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * A json annotated rest model for System Configuration for PUT. + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class TenantConfigurationValueRequest { + + @JsonProperty + private Object value; + + /** + * + * @return the value of the TenantConfigurationValueRequest + */ + public Object getValue() { + return value; + } + + /** + * Sets teh TenantConfigurationValueRequest + * + * @param value + */ + public void setValue(final Object value) { + this.value = value; + } + +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java index bb938a780..25ddc7c4c 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/ResponseExceptionHandler.java @@ -66,6 +66,7 @@ public class ResponseExceptionHandler { ERROR_TO_HTTP_STATUS.put(SpServerError.SP_ENTITY_LOCKED, HttpStatus.LOCKED); 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); } private static HttpStatus getStatusOrDefault(final SpServerError error) { diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java index 0a430223c..ffd669a61 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java @@ -148,8 +148,8 @@ public class SystemManagementResource { public ResponseEntity addUpdateConfig(@RequestBody final TenantConfigurationRest configuration, @PathVariable final String key) { - // TODO Quick and dirty to stay compatible, but these rest interface - // won't be necessary in future + // TODO Quick and dirty solution to stay compatible, but these rest + // interface won't be necessary in future Object value; if (configuration.getValue().equals(Boolean.TRUE)) { diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java index 75add4be5..fc63e8bb1 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java @@ -5,50 +5,55 @@ import java.util.Map; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRest; import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationValueRest; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +/** + * A mapper which maps repository model to RESTful model representation and + * back. + */ final public class SystemMapper { - private static final Logger LOG = LoggerFactory.getLogger(SystemMapper.class); - private SystemMapper() { // Utility class } - private static DurationHelper dh = new DurationHelper(); - - public static SystemConfigurationRest toResponse( + /** + * @param tenantConfigurationManagement + * instance of TenantConfigurationManagement + * @return a map of all existing configuration values + */ + public static Map toResponse( final TenantConfigurationManagement tenantConfigurationManagement) { - final SystemConfigurationRest sysconf = new SystemConfigurationRest(); - - final Map authconf = new HashMap(); + final Map configurationMap = new HashMap(); for (final TenantConfigurationKey key : TenantConfigurationKey.values()) { - final TenantConfigurationValueRest value = toResponse( - tenantConfigurationManagement.getConfigurationValue(key, key.getDataType())); - authconf.put(key.getKeyName(), value); + configurationMap.put(key.getKeyName(), + toResponse(tenantConfigurationManagement.getConfigurationValue(key))); } - sysconf.setConfiguration(authconf); - return sysconf; + return configurationMap; } - public static TenantConfigurationValueRest toResponse(final TenantConfigurationValue confValue) { - final TenantConfigurationValueRest response = new TenantConfigurationValueRest(); + /** + * maps a TenantConfigurationValue from the repository model to a + * TenantConfigurationValueRest, the RESTful model. + * + * @param repoConfValue + * configuration value as repository model + * @return configuration value as RESTful model + */ + public static TenantConfigurationValueRest toResponse(final TenantConfigurationValue repoConfValue) { + final TenantConfigurationValueRest restConfValue = new TenantConfigurationValueRest(); - response.setValue(confValue.getValue()); - response.setGlobal(confValue.isGlobal()); - response.setCreatedAt(confValue.getCreatedAt()); - response.setCreatedBy(confValue.getCreatedBy()); - response.setLastModifiedAt(confValue.getLastModifiedAt()); - response.setLastModifiedBy(confValue.getLastModifiedBy()); + restConfValue.setValue(repoConfValue.getValue()); + restConfValue.setGlobal(repoConfValue.isGlobal()); + restConfValue.setCreatedAt(repoConfValue.getCreatedAt()); + restConfValue.setCreatedBy(repoConfValue.getCreatedBy()); + restConfValue.setLastModifiedAt(repoConfValue.getLastModifiedAt()); + restConfValue.setLastModifiedBy(repoConfValue.getLastModifiedBy()); - return response; + return restConfValue; } } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java index 888d3045a..716687b03 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java @@ -1,46 +1,115 @@ package org.eclipse.hawkbit.rest.resource; -import org.eclipse.hawkbit.repository.DistributionSetManagement; +import java.util.Map; + import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRequestBodyPut; -import org.eclipse.hawkbit.rest.resource.model.system.SystemConfigurationRest; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; +import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationValueRequest; +import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationValueRest; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +/** + * REST Resource handling tenant specific configuration operations. + * + * + * + * + */ @RestController @RequestMapping(RestConstants.SYSTEM_V1_REQUEST_MAPPING) public class SystemResource { - private static final Logger LOGGER = LoggerFactory.getLogger(SystemResource.class); + private static final Logger LOG = LoggerFactory.getLogger(SystemResource.class); @Autowired private TenantConfigurationManagement tenantConfigurationManagement; - @Autowired - private DistributionSetManagement distributionSetManagement; - + /** + * @return a Map of all configuration values. + */ @RequestMapping(method = RequestMethod.GET, value = "/conf", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getSystemConfiguration() { + public ResponseEntity> getSystemConfiguration() { return new ResponseEntity<>(SystemMapper.toResponse(tenantConfigurationManagement), HttpStatus.OK); } - @RequestMapping(method = RequestMethod.PUT, value = "/conf", consumes = { "application/hal+json", + /** + * Handles the DELETE request of deleting a tenant specific configuration + * value within SP. + * + * @param keyName + * the Name of the configuration key + * @return If the given configuration value exists and could be deleted Http + * OK. In any failure the JsonResponseExceptionHandler is handling + * the response. + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/conf/{keyName}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity deleteConfigurationValue(@PathVariable final String keyName) { + + final TenantConfigurationKey configKey = TenantConfigurationKey.fromKeyName(keyName); + + tenantConfigurationManagement.deleteConfiguration(configKey); + + LOG.debug("{} config value deleted, return status {}", keyName, HttpStatus.OK); + return new ResponseEntity<>(HttpStatus.OK); + } + + /** + * Handles the GET request of deleting a tenant specific configuration value + * within SP. + * + * @param keyName + * the Name of the configuration key + * @return If the given configuration value exists and could be get Http OK. + * In any failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.GET, value = "/conf/{keyName}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getConfigurationValue(@PathVariable final String keyName) { + + final TenantConfigurationKey configKey = TenantConfigurationKey.fromKeyName(keyName); + + LOG.debug("{} config value getted, return status {}", keyName, HttpStatus.OK); + return new ResponseEntity<>( + SystemMapper.toResponse(tenantConfigurationManagement.getConfigurationValue(configKey)), HttpStatus.OK); + } + + /** + * Handles the GET request of deleting a tenant specific configuration value + * within SP. + * + * @param keyName + * the Name of the configuration key + * @param configurationValueRest + * the new value for the configuration + * @return If the given configuration value exists and could be get Http OK. + * In any failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.PUT, value = "/conf/{keyName}", consumes = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity updateSoftwareModuleType( - @RequestBody final SystemConfigurationRequestBodyPut systemConReq) { + public ResponseEntity updateConfigurationValue(@PathVariable final String keyName, + @RequestBody final TenantConfigurationValueRequest configurationValueRest) { - // systemManagement.updateTenantConfiguration(systemConReq); + final TenantConfigurationKey configKey = TenantConfigurationKey.fromKeyName(keyName); - return new ResponseEntity<>(SystemMapper.toResponse(tenantConfigurationManagement), HttpStatus.OK); + final TenantConfigurationValue updatedValue = tenantConfigurationManagement + + .addOrUpdateConfiguration(configKey, configurationValueRest.getValue()); + return new ResponseEntity<>(SystemMapper.toResponse(updatedValue), HttpStatus.OK); } -} +} \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 016e5eb6d..6ca93e982 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -62,8 +62,10 @@ public class PollingConfigurationView extends BaseConfigurationView minDuration = durationHelper.formattedStringToDuration(controllerPollProperties.getMinPollingTime()); maxDuration = durationHelper.formattedStringToDuration(controllerPollProperties.getMaxPollingTime()); - globalPollTime = durationHelper.formattedStringToDuration(controllerPollProperties.getPollingTime()); - globalOverdueTime = durationHelper.formattedStringToDuration(controllerPollProperties.getPollingOverdueTime()); + globalPollTime = durationHelper.formattedStringToDuration(tenantConfigurationManagement + .getGlobalConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class)); + globalOverdueTime = durationHelper.formattedStringToDuration(tenantConfigurationManagement + .getGlobalConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class)); final TenantConfigurationValue pollTimeConfValue = tenantConfigurationManagement .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class); From 6a88f2a3f40deb644a9702e97b11598bc0ee0e72 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Fri, 29 Jan 2016 16:28:46 +0100 Subject: [PATCH 21/42] Added Permission for TenantConfiguration changes - created SpringEvalExpression for the right to change tenant configuration - added this authorization filter to every tenant configuration related method Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/repository/TenantConfigurationManagement.java | 8 ++++++++ .../eclipse/hawkbit/im/authentication/SpPermission.java | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 74c864748..522437bd0 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -1,5 +1,6 @@ package org.eclipse.hawkbit.repository; +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; @@ -14,6 +15,7 @@ import org.springframework.core.convert.support.ConfigurableConversionService; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.env.Environment; import org.springframework.data.jpa.repository.Modifying; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -69,7 +71,9 @@ public class TenantConfigurationManagement implements EnvironmentAware { * if the property cannot be converted to the given * {@code propertyType} */ + @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) throws TenantConfigurationValidatorException { @@ -116,6 +120,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { * if the property cannot be converted to the given * {@code propertyType} */ + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey) throws TenantConfigurationValidatorException { return getConfigurationValue(configurationKey, configurationKey.getDataType()); @@ -142,6 +147,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { * {@code propertyType} */ @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public T getGlobalConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) throws TenantConfigurationValidatorException { @@ -178,6 +184,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { @CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") @Transactional @Modifying + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public TenantConfigurationValue addOrUpdateConfiguration(final TenantConfigurationKey configurationKey, final T value) { @@ -223,6 +230,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { @CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") @Transactional @Modifying + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public void deleteConfiguration(final TenantConfigurationKey configurationKey) { tenantConfigurationRepository.deleteByKey(configurationKey.getKeyName()); } 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 d105f8d70..5d4ab9283 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 @@ -308,6 +308,13 @@ public final class SpPermission { 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; + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#TENANT_CONFIGURATION} + */ + public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION + + HAS_AUTH_SUFFIX; + private SpringEvalExpressions() { // utility class } From c39753001ed74c37d0a607d7c05b24a2304eba5d Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Fri, 29 Jan 2016 18:10:42 +0100 Subject: [PATCH 22/42] Bugfix: Setting and getting configuration values - removed cache from global getter, because it was overriding the cache of the tenant specific getter - changed Type of AuthName key, type of key was not important before the huge configuration refactoring - fixed test conditions Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/tenancy/configuration/TenantConfigurationKey.java | 4 ++-- .../hawkbit/repository/TenantConfigurationManagement.java | 1 - .../hawkbit/repository/TenantConfigurationManagementTest.java | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index fc1e3a856..1f5481dc0 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -35,8 +35,8 @@ public enum TenantConfigurationKey { * */ AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", - "hawkbit.server.controller.security.authentication.header.authority", Boolean.class, - Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class), + "hawkbit.server.controller.security.authentication.header.authority", String.class, + Boolean.FALSE.toString(), TenantConfigurationStringValidator.class), /** * boolean value {@code true} {@code false}. */ diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 522437bd0..85432e8a2 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -146,7 +146,6 @@ public class TenantConfigurationManagement implements EnvironmentAware { * if the property cannot be converted to the given * {@code propertyType} */ - @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) public T getGlobalConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) throws TenantConfigurationValidatorException { diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java index 6b267aa24..1fb41048f 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java @@ -14,7 +14,6 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException; import org.junit.Assert; import org.junit.Test; -import org.springframework.core.convert.ConversionFailedException; import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; @@ -86,7 +85,7 @@ public class TenantConfigurationManagementTest extends AbstractIntegrationTestWi .isEqualTo(value2); } - @Test(expected = ConversionFailedException.class) + @Test(expected = TenantConfigurationValidatorException.class) @Description("Tests that the get configuration throws exception in case the value cannot be automatically converted from String to Boolean") public void wrongTenantConfigurationValueTypeThrowsException() { final TenantConfigurationKey configKey = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_ENABLED; From aee254244afccec3df33f8684d1d9e9ba36b2dbd Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Mon, 1 Feb 2016 15:31:56 +0100 Subject: [PATCH 23/42] Smaller Improvements of configuration REST-API * changed resource path to "rest/v1/system/configs" * added links to resources, to follow good practice recommendations * added GET methode for parent resource system/configs * fade out null values in json * marked some json properties as mandatory TMP Signed-off-by: Nonnenmacher Fabian --- .../TenantConfigurationValueRequest.java | 4 +-- .../system/TenantConfigurationValueRest.java | 14 +++++++++- .../hawkbit/rest/resource/SystemMapper.java | 10 +++++-- .../hawkbit/rest/resource/SystemResource.java | 27 +++++++++++++------ ...yTokenAuthenticationConfigurationItem.java | 3 +-- 5 files changed, 43 insertions(+), 15 deletions(-) diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java index f6be11c51..91a8820f1 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java @@ -12,7 +12,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties(ignoreUnknown = true) public class TenantConfigurationValueRequest { - @JsonProperty + @JsonProperty(required = true) private Object value; /** @@ -24,7 +24,7 @@ public class TenantConfigurationValueRequest { } /** - * Sets teh TenantConfigurationValueRequest + * Sets the TenantConfigurationValueRequest * * @param value */ diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java index 78ebef8c3..cf4a487a4 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java @@ -1,9 +1,21 @@ package org.eclipse.hawkbit.rest.resource.model.system; -public class TenantConfigurationValueRest { +import org.springframework.hateoas.ResourceSupport; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class TenantConfigurationValueRest extends ResourceSupport { + + @JsonInclude(Include.ALWAYS) private Object value = null; + + @JsonInclude(Include.ALWAYS) private boolean isGlobal = true; + private Long lastModifiedAt = null; private String lastModifiedBy = null; private Long createdAt = null; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java index fc63e8bb1..1f6790921 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java @@ -1,5 +1,8 @@ package org.eclipse.hawkbit.rest.resource; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + import java.util.HashMap; import java.util.Map; @@ -30,7 +33,7 @@ final public class SystemMapper { for (final TenantConfigurationKey key : TenantConfigurationKey.values()) { configurationMap.put(key.getKeyName(), - toResponse(tenantConfigurationManagement.getConfigurationValue(key))); + toResponse(key.getKeyName(), tenantConfigurationManagement.getConfigurationValue(key))); } return configurationMap; @@ -44,7 +47,8 @@ final public class SystemMapper { * configuration value as repository model * @return configuration value as RESTful model */ - public static TenantConfigurationValueRest toResponse(final TenantConfigurationValue repoConfValue) { + public static TenantConfigurationValueRest toResponse(final String key, + final TenantConfigurationValue repoConfValue) { final TenantConfigurationValueRest restConfValue = new TenantConfigurationValueRest(); restConfValue.setValue(repoConfValue.getValue()); @@ -54,6 +58,8 @@ final public class SystemMapper { restConfValue.setLastModifiedAt(repoConfValue.getLastModifiedAt()); restConfValue.setLastModifiedBy(repoConfValue.getLastModifiedBy()); + restConfValue.add(linkTo(methodOn(SystemResource.class).getConfigurationValue(key)).withRel("self")); + return restConfValue; } } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java index 716687b03..cd4a0fa1f 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java @@ -1,5 +1,8 @@ package org.eclipse.hawkbit.rest.resource; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; +import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; + import java.util.Map; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; @@ -10,6 +13,7 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.hateoas.ResourceSupport; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -35,10 +39,17 @@ public class SystemResource { @Autowired private TenantConfigurationManagement tenantConfigurationManagement; + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getSystem() { + final ResourceSupport resourceSupport = new ResourceSupport(); + resourceSupport.add(linkTo(methodOn(SystemResource.class).getSystemConfiguration()).withRel("configs")); + return ResponseEntity.ok(resourceSupport); + } + /** * @return a Map of all configuration values. */ - @RequestMapping(method = RequestMethod.GET, value = "/conf", produces = { "application/hal+json", + @RequestMapping(method = RequestMethod.GET, value = "/configs", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity> getSystemConfiguration() { return new ResponseEntity<>(SystemMapper.toResponse(tenantConfigurationManagement), HttpStatus.OK); @@ -54,7 +65,7 @@ public class SystemResource { * OK. In any failure the JsonResponseExceptionHandler is handling * the response. */ - @RequestMapping(method = RequestMethod.DELETE, value = "/conf/{keyName}", produces = { "application/hal+json", + @RequestMapping(method = RequestMethod.DELETE, value = "/configs/{keyName}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity deleteConfigurationValue(@PathVariable final String keyName) { @@ -63,7 +74,7 @@ public class SystemResource { tenantConfigurationManagement.deleteConfiguration(configKey); LOG.debug("{} config value deleted, return status {}", keyName, HttpStatus.OK); - return new ResponseEntity<>(HttpStatus.OK); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); } /** @@ -76,15 +87,15 @@ public class SystemResource { * In any failure the JsonResponseExceptionHandler is handling the * response. */ - @RequestMapping(method = RequestMethod.GET, value = "/conf/{keyName}", produces = { "application/hal+json", + @RequestMapping(method = RequestMethod.GET, value = "/configs/{keyName}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity getConfigurationValue(@PathVariable final String keyName) { final TenantConfigurationKey configKey = TenantConfigurationKey.fromKeyName(keyName); LOG.debug("{} config value getted, return status {}", keyName, HttpStatus.OK); - return new ResponseEntity<>( - SystemMapper.toResponse(tenantConfigurationManagement.getConfigurationValue(configKey)), HttpStatus.OK); + return new ResponseEntity<>(SystemMapper.toResponse(configKey.getKeyName(), + tenantConfigurationManagement.getConfigurationValue(configKey)), HttpStatus.OK); } /** @@ -99,7 +110,7 @@ public class SystemResource { * In any failure the JsonResponseExceptionHandler is handling the * response. */ - @RequestMapping(method = RequestMethod.PUT, value = "/conf/{keyName}", consumes = { "application/hal+json", + @RequestMapping(method = RequestMethod.PUT, value = "/configs/{keyName}", consumes = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) public ResponseEntity updateConfigurationValue(@PathVariable final String keyName, @RequestBody final TenantConfigurationValueRequest configurationValueRest) { @@ -109,7 +120,7 @@ public class SystemResource { final TenantConfigurationValue updatedValue = tenantConfigurationManagement .addOrUpdateConfiguration(configKey, configurationValueRest.getValue()); - return new ResponseEntity<>(SystemMapper.toResponse(updatedValue), HttpStatus.OK); + return new ResponseEntity<>(SystemMapper.toResponse(keyName, updatedValue), HttpStatus.OK); } } \ No newline at end of file diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java index 12bfae7c6..0d3f496ba 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/GatewaySecurityTokenAuthenticationConfigurationItem.java @@ -61,8 +61,7 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac private VerticalLayout detailLayout; /** - * @param configurationKey - * @param systemManagement + * @param tenantConfigurationManagement */ @Autowired public GatewaySecurityTokenAuthenticationConfigurationItem( From 08d4509249e8e5e3c565fe7c65d548fbb5b2f983 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Mon, 1 Feb 2016 15:39:49 +0100 Subject: [PATCH 24/42] Added tests for REST api - added acceptance test for every possible methode type - added negative tests for restcalls which leads to bad requests Signed-off-by: Nonnenmacher Fabian --- .../resource/ConfigurationResourceTest.java | 138 ++++++++++++++++++ .../PollingConfigurationView.java | 15 +- 2 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.java diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.java new file mode 100644 index 000000000..5c359ea3f --- /dev/null +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.java @@ -0,0 +1,138 @@ +package org.eclipse.hawkbit.rest.resource; + +import static org.fest.assertions.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.Matchers.hasSize; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import org.eclipse.hawkbit.AbstractIntegrationTest; +import org.eclipse.hawkbit.MockMvcResultPrinter; +import org.eclipse.hawkbit.exception.SpServerError; +import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; +import org.eclipse.hawkbit.rest.resource.model.ExceptionInfo; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.junit.Test; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; + +import ru.yandex.qatools.allure.annotations.Description; +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +@Features("Component Tests - Management RESTful API") +@Stories("ConfigurationResource") +public class ConfigurationResourceTest extends AbstractIntegrationTest { + + private static String BASE_JSON_REQUEST_STRING = "{\"value\":\"%s\"}"; + + @Test + @Description("perform a GET request on all existing configurations.") + public void getConfigurationValues() throws Exception { + + final ResultActions resultActions = mvc.perform(get(RestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/")) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.*", hasSize(TenantConfigurationKey.values().length))); + + for (final TenantConfigurationKey key : TenantConfigurationKey.values()) { + + final TenantConfigurationValue confValue = tenantConfigurationManagement.getConfigurationValue(key); + resultActions.andExpect(jsonPath("$.['" + key.getKeyName() + "'].value", equalTo(confValue.getValue()))) + .andExpect(jsonPath("$.['" + key.getKeyName() + "'].global", equalTo(confValue.isGlobal()))); + } + } + + @Test + @Description("perform a GET request on a existing configuration key.") + public void getConfigurationValue() throws Exception { + + final TenantConfigurationKey key = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME; + final String notGlobalValue = "notTheGlobalHeaderAuthoryName"; + + tenantConfigurationManagement.addOrUpdateConfiguration(key, notGlobalValue); + + mvc.perform(get(RestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{configId}/", key.getKeyName())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("value", equalTo(notGlobalValue))).andExpect(jsonPath("global", equalTo(false))) + .andExpect(jsonPath("createdAt", notNullValue())).andExpect(jsonPath("createdBy", notNullValue())); + } + + @Test + @Description("perform a PUT request on a existing configuration key with a valid value.") + public void putConfigurationValue() throws Exception { + + final TenantConfigurationKey key = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME; + final String testValue = "12:12:12"; + + mvc.perform(put(RestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{configId}/", key.getKeyName()) + .content(String.format(BASE_JSON_REQUEST_STRING, testValue)).contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); + + assertThat(tenantConfigurationManagement.getConfigurationValue(key, String.class).getValue()) + .isEqualTo(testValue); + } + + @Test + @Description("perform a DELETE request on a existing configuration key.") + public void deleteConfigurationValue() throws Exception { + + final TenantConfigurationKey key = TenantConfigurationKey.AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME; + final String notGlobalValue = "notTheGlobalHeaderAuthoryName"; + + tenantConfigurationManagement.addOrUpdateConfiguration(key, notGlobalValue); + assertThat(tenantConfigurationManagement.getConfigurationValue(key, String.class).isGlobal()).isEqualTo(false); + + assertThat(tenantConfigurationManagement.getConfigurationValue(key, String.class).getValue()) + .isEqualTo(notGlobalValue); + + mvc.perform(delete(RestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{configId}/", key.getKeyName())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isNoContent()); + + assertThat(tenantConfigurationManagement.getConfigurationValue(key, String.class).isGlobal()).isEqualTo(true); + assertThat(tenantConfigurationManagement.getConfigurationValue(key, String.class).getValue()) + .isNotEqualTo(notGlobalValue); + } + + @Test + @Description("perform a (put) request on a not existing configuration key.") + public void putInvalidConfigurationKey() throws Exception { + + final String notExistingKey = "notExistingKey"; + final String testValue = "12:12:12"; + + final MvcResult mvcResult = mvc + .perform(put(RestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{configId}", notExistingKey) + .content(String.format(BASE_JSON_REQUEST_STRING, testValue)) + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn(); + + // verify response json exception message + final ExceptionInfo exceptionInfo = ResourceUtility + .convertException(mvcResult.getResponse().getContentAsString()); + assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_CONFIGURATION_KEY_INVALID.getKey()); + } + + @Test + @Description("perform a put request with a not matching configuration value.") + public void putInvalidConfigurationValue() throws Exception { + + final TenantConfigurationKey key = TenantConfigurationKey.POLLING_TIME_INTERVAL; + final String testValue = "invalidFormattedDuration"; + + final MvcResult mvcResult = mvc + .perform(put(RestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{configId}", key.getKeyName()) + .content(String.format(BASE_JSON_REQUEST_STRING, testValue)) + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()).andReturn(); + + // verify response json exception message + final ExceptionInfo exceptionInfo = ResourceUtility + .convertException(mvcResult.getResponse().getContentAsString()); + assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_CONFIGURATION_VALUE_INVALID.getKey()); + } +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 6ca93e982..e8ca6a61f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -112,14 +112,21 @@ public class PollingConfigurationView extends BaseConfigurationView if (!compareDurations(tenantPollTime, fieldPollTime.getValue())) { tenantPollTime = fieldPollTime.getValue(); - tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, - durationHelper.durationToFormattedString(tenantPollTime)); + saveDurationConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, tenantPollTime); } if (!compareDurations(tenantOverdueTime, fieldPollingOverdueTime.getValue())) { tenantOverdueTime = fieldPollingOverdueTime.getValue(); - tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, - durationHelper.durationToFormattedString(tenantOverdueTime)); + saveDurationConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, tenantOverdueTime); + } + } + + private void saveDurationConfigurationValue(final TenantConfigurationKey key, final Duration duration) { + if (duration == null) { + tenantConfigurationManagement.deleteConfiguration(key); + } else { + tenantConfigurationManagement.addOrUpdateConfiguration(key, + durationHelper.durationToFormattedString(duration)); } } From ffa46afc7a54579c38648e7fab2778f41d4b3834 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Tue, 2 Feb 2016 19:10:59 +0100 Subject: [PATCH 25/42] Removed old REST api for changing configuration values Signed-off-by: Nonnenmacher Fabian --- .../model/system/TenantConfigurationRest.java | 55 ------------------- .../resource/SystemManagementResource.java | 34 ------------ 2 files changed, 89 deletions(-) delete mode 100644 hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java deleted file mode 100644 index 0c8a8e54d..000000000 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationRest.java +++ /dev/null @@ -1,55 +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.rest.resource.model.system; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * Response body for tenant configuration requests. - * - */ -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class TenantConfigurationRest { - - private String key; - private Object value; - - /** - * @return the key - */ - public String getKey() { - return key; - } - - /** - * @param key - * the key to set - */ - public void setKey(final String key) { - this.key = key; - } - - /** - * @return the value - */ - public Object getValue() { - return value; - } - - /** - * @param value - * the value to set - */ - public void setValue(final Object value) { - this.value = value; - } -} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java index ffd669a61..93e1acb3a 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java @@ -20,9 +20,7 @@ import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.rest.resource.model.system.CacheRest; import org.eclipse.hawkbit.rest.resource.model.system.SystemStatisticsRest; -import org.eclipse.hawkbit.rest.resource.model.system.TenantConfigurationRest; import org.eclipse.hawkbit.rest.resource.model.system.TenantSystemUsageRest; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -33,7 +31,6 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @@ -133,37 +130,6 @@ public class SystemManagementResource { return ResponseEntity.ok(cacheNames); } - /** - * Adds or updates a configuration for a specific tenant to the tenant - * configuration. - * - * @param configuration - * the configuration value to add or update - * @param key - * the key of the configuration to add or update - * @return the response entity with status OK. - */ - @RequestMapping(method = RequestMethod.PUT, value = "/conf/{key}") - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN) - public ResponseEntity addUpdateConfig(@RequestBody final TenantConfigurationRest configuration, - @PathVariable final String key) { - - // TODO Quick and dirty solution to stay compatible, but these rest - // interface won't be necessary in future - - Object value; - if (configuration.getValue().equals(Boolean.TRUE)) { - value = true; - } else if (configuration.getValue().equals(Boolean.FALSE)) { - value = false; - } else { - value = configuration.getValue(); - } - - tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.fromKeyName(key), value); - return ResponseEntity.ok().build(); - } - private CacheRest cacheRest(final Cache cache) { final Object nativeCache = cache.getNativeCache(); if (nativeCache instanceof com.google.common.cache.Cache) { From 016350de4eca683c39059c15ab632d13658c75d6 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Fri, 5 Feb 2016 09:37:20 +0100 Subject: [PATCH 26/42] Moved SystemManagementResources in other package than SystemResources * moved classes to new package to seperate it from SystemResource * updated references Signed-off-by: Nonnenmacher Fabian --- .../model/{system => systemmanagement}/CacheRest.java | 2 +- .../{system => systemmanagement}/SystemStatisticsRest.java | 2 +- .../{system => systemmanagement}/TenantSystemUsageRest.java | 2 +- .../hawkbit/rest/resource/SystemManagementResource.java | 6 +++--- .../org/eclipse/hawkbit/rest/resource/SystemMapper.java | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) rename hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/{system => systemmanagement}/CacheRest.java (95%) rename hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/{system => systemmanagement}/SystemStatisticsRest.java (97%) rename hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/{system => systemmanagement}/TenantSystemUsageRest.java (96%) diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/CacheRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/CacheRest.java similarity index 95% rename from hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/CacheRest.java rename to hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/CacheRest.java index e430cba1c..35d35c0b1 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/CacheRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/CacheRest.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.rest.resource.model.system; +package org.eclipse.hawkbit.rest.resource.model.systemmanagement; import java.util.Collection; diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemStatisticsRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/SystemStatisticsRest.java similarity index 97% rename from hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemStatisticsRest.java rename to hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/SystemStatisticsRest.java index 84ce69948..c69201d69 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/SystemStatisticsRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/SystemStatisticsRest.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.rest.resource.model.system; +package org.eclipse.hawkbit.rest.resource.model.systemmanagement; import java.util.List; diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantSystemUsageRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/TenantSystemUsageRest.java similarity index 96% rename from hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantSystemUsageRest.java rename to hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/TenantSystemUsageRest.java index b300d94de..bc8653b36 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantSystemUsageRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/systemmanagement/TenantSystemUsageRest.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.rest.resource.model.system; +package org.eclipse.hawkbit.rest.resource.model.systemmanagement; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java index 93e1acb3a..b3a461915 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemManagementResource.java @@ -18,9 +18,9 @@ import org.eclipse.hawkbit.report.model.SystemUsageReport; import org.eclipse.hawkbit.report.model.TenantUsage; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; -import org.eclipse.hawkbit.rest.resource.model.system.CacheRest; -import org.eclipse.hawkbit.rest.resource.model.system.SystemStatisticsRest; -import org.eclipse.hawkbit.rest.resource.model.system.TenantSystemUsageRest; +import org.eclipse.hawkbit.rest.resource.model.systemmanagement.CacheRest; +import org.eclipse.hawkbit.rest.resource.model.systemmanagement.SystemStatisticsRest; +import org.eclipse.hawkbit.rest.resource.model.systemmanagement.TenantSystemUsageRest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java index 1f6790921..31d7ef062 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java @@ -15,7 +15,7 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; * A mapper which maps repository model to RESTful model representation and * back. */ -final public class SystemMapper { +public class SystemMapper { private SystemMapper() { // Utility class @@ -29,7 +29,7 @@ final public class SystemMapper { public static Map toResponse( final TenantConfigurationManagement tenantConfigurationManagement) { - final Map configurationMap = new HashMap(); + final Map configurationMap = new HashMap<>(); for (final TenantConfigurationKey key : TenantConfigurationKey.values()) { configurationMap.put(key.getKeyName(), From 57e040aec1aeb681629212f2296477497c912b45 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Fri, 5 Feb 2016 10:44:47 +0100 Subject: [PATCH 27/42] Fixup merge conflict Signed-off-by: Nonnenmacher Fabian --- .../java/org/eclipse/hawkbit/exception/SpServerError.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 c7eb2b159..003b31cd7 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 @@ -185,8 +185,8 @@ public enum SpServerError { /** * */ - SP_CONFIGURATION_KEY_INVALID("hawkbit.server.error.configKeyInvalid", "The given configuration key is invalid."); - + SP_CONFIGURATION_KEY_INVALID("hawkbit.server.error.configKeyInvalid", "The given configuration key is invalid."), + /** * */ From 2be492261598d4ee006af422b57ac946919098b3 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Fri, 5 Feb 2016 11:01:06 +0100 Subject: [PATCH 28/42] Added System Security Context as attribute to AbstractControllerAuthenticationFilter This is necessary, because the tenant configuration methods are only accessable with specific permissions. With the SystemSecurityContext methods can be executed as SystemRunner and therefor we can set permissions. * updated the chaine of condtructors to set the context in the filter class * added SystemRunner permission to TenantConfigurationManagement * Autowired the system context to AMQP and HTTP controller Signed-off-by: Nonnenmacher Fabian --- .../SecurityManagedConfiguration.java | 9 ++++++--- .../amqp/AmqpControllerAuthentfication.java | 10 +++++++--- ...actHttpControllerAuthenticationFilter.java | 4 +++- ...lerPreAuthenticateSecurityTokenFilter.java | 6 +++--- ...thenticatedGatewaySecurityTokenFilter.java | 8 +++++--- ...rPreAuthenticatedSecurityHeaderFilter.java | 6 +++--- .../TenantConfigurationManagement.java | 3 ++- ...bstractControllerAuthenticationFilter.java | 9 ++++++--- ...lerPreAuthenticateSecurityTokenFilter.java | 12 +++++++---- ...thenticatedGatewaySecurityTokenFilter.java | 20 +++++++++++++------ ...rPreAuthenticatedSecurityHeaderFilter.java | 14 +++++++------ 11 files changed, 65 insertions(+), 36 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 c7301efd1..73baa6c5a 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 @@ -39,6 +39,7 @@ import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeader import org.eclipse.hawkbit.security.HttpDownloadAuthenticationFilter; import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider; import org.eclipse.hawkbit.security.SecurityProperties; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -127,6 +128,8 @@ public class SecurityManagedConfiguration implements EnvironmentAware { private SecurityProperties securityConfiguration; @Autowired private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties; + @Autowired + private SystemSecurityContext systemSecurityContext; @Override protected void configure(final HttpSecurity http) throws Exception { @@ -134,19 +137,19 @@ public class SecurityManagedConfiguration implements EnvironmentAware { final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter( securityConfiguration.getRpCnHeader(), securityConfiguration.getRpSslIssuerHashHeader(), - tenantConfigurationManagement, tenantAware); + tenantConfigurationManagement, tenantAware, systemSecurityContext); securityHeaderFilter.setAuthenticationManager(authenticationManager()); securityHeaderFilter.setCheckForPrincipalChanges(true); securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource); final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter( - tenantConfigurationManagement, tenantAware, controllerManagement); + tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext); securityTokenFilter.setAuthenticationManager(authenticationManager()); securityTokenFilter.setCheckForPrincipalChanges(true); securityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource); final HttpControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new HttpControllerPreAuthenticatedGatewaySecurityTokenFilter( - tenantConfigurationManagement, tenantAware); + tenantConfigurationManagement, tenantAware, systemSecurityContext); gatewaySecurityTokenFilter.setAuthenticationManager(authenticationManager()); gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true); gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource); diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java index f19907a99..c708ac0c7 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java @@ -24,6 +24,7 @@ import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilt import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider; import org.eclipse.hawkbit.security.PreAuthenficationFilter; import org.eclipse.hawkbit.security.SecurityProperties; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,6 +58,9 @@ public class AmqpControllerAuthentfication { @Autowired private SecurityProperties secruityProperties; + @Autowired + private SystemSecurityContext systemSecurityContext; + /** * Constructor. */ @@ -74,16 +78,16 @@ public class AmqpControllerAuthentfication { private void addFilter() { final ControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new ControllerPreAuthenticatedGatewaySecurityTokenFilter( - tenantConfigurationManagement, tenantAware); + tenantConfigurationManagement, tenantAware, systemSecurityContext); filterChain.add(gatewaySecurityTokenFilter); final ControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new ControllerPreAuthenticatedSecurityHeaderFilter( secruityProperties.getRpCnHeader(), secruityProperties.getRpSslIssuerHashHeader(), - tenantConfigurationManagement, tenantAware); + tenantConfigurationManagement, tenantAware, systemSecurityContext); filterChain.add(securityHeaderFilter); final ControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new ControllerPreAuthenticateSecurityTokenFilter( - tenantConfigurationManagement, controllerManagement, tenantAware); + tenantConfigurationManagement, controllerManagement, tenantAware, systemSecurityContext); filterChain.add(securityTokenFilter); filterChain.add(new CoapAnonymousPreAuthenticatedFilter()); diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java index e4d79b3c4..adb2858b9 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java @@ -57,6 +57,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac + "}/controller/artifacts/v1/**"; protected TenantConfigurationManagement tenantConfigurationManagement; protected TenantAware tenantAware; + protected SystemSecurityContext systemSecurityContext; private final AntPathMatcher pathExtractor; @@ -71,9 +72,10 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac * the tenant aware service */ public AbstractHttpControllerAuthenticationFilter(final TenantConfigurationManagement tenantConfigurationManagement, - final TenantAware tenantAware) { + final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) { this.tenantConfigurationManagement = tenantConfigurationManagement; this.tenantAware = tenantAware; + this.systemSecurityContext = systemSecurityContext; pathExtractor = new AntPathMatcher(); } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java index e18a90008..c7106e6dd 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java @@ -47,15 +47,15 @@ public class HttpControllerPreAuthenticateSecurityTokenFilter extends AbstractHt */ public HttpControllerPreAuthenticateSecurityTokenFilter( final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, - final ControllerManagement controllerManagement) { - super(tenantConfigurationManagement, tenantAware); + final ControllerManagement controllerManagement, final SystemSecurityContext systemSecurityContext) { + super(tenantConfigurationManagement, tenantAware, systemSecurityContext); this.controllerManagement = controllerManagement; } @Override protected PreAuthenficationFilter createControllerAuthenticationFilter() { return new ControllerPreAuthenticateSecurityTokenFilter(tenantConfigurationManagement, controllerManagement, - tenantAware); + tenantAware, systemSecurityContext); } } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java index b62ac1db4..3d32811ce 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -35,13 +35,15 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter * tenant */ public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter( - final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware) { - super(tenantConfigurationManagement, tenantAware); + final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, + final SystemSecurityContext systemSecurityContext) { + super(tenantConfigurationManagement, tenantAware, systemSecurityContext); } @Override protected PreAuthenficationFilter createControllerAuthenticationFilter() { - return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(tenantConfigurationManagement, tenantAware); + return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(tenantConfigurationManagement, tenantAware, + systemSecurityContext); } } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java index 5a67dda14..58e6be4a9 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java @@ -45,8 +45,8 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract */ public HttpControllerPreAuthenticatedSecurityHeaderFilter(final String caCommonNameHeader, final String caAuthorityNameHeader, final TenantConfigurationManagement tenantConfigurationManagement, - final TenantAware tenantAware) { - super(tenantConfigurationManagement, tenantAware); + final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) { + super(tenantConfigurationManagement, tenantAware, systemSecurityContext); this.caCommonNameHeader = caCommonNameHeader; this.caAuthorityNameHeader = caAuthorityNameHeader; } @@ -54,7 +54,7 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract @Override protected PreAuthenficationFilter createControllerAuthenticationFilter() { return new ControllerPreAuthenticatedSecurityHeaderFilter(caCommonNameHeader, caAuthorityNameHeader, - tenantConfigurationManagement, tenantAware); + tenantConfigurationManagement, tenantAware, systemSecurityContext); } } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 85432e8a2..2697abf6e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -73,7 +73,8 @@ public class TenantConfigurationManagement implements EnvironmentAware { */ @Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()") - @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) + @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_SYSTEM_CODE) public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) throws TenantConfigurationValidatorException { diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java index 552bbae06..d22c432cf 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java @@ -29,11 +29,13 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe protected final TenantConfigurationManagement tenantConfigurationManagement; protected final TenantAware tenantAware; private final SecurityConfigurationKeyTenantRunner configurationKeyTenantRunner; + protected final SystemSecurityContext systemSecurityContext; protected AbstractControllerAuthenticationFilter(final TenantConfigurationManagement systemManagement, - final TenantAware tenantAware) { + final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) { this.tenantConfigurationManagement = systemManagement; this.tenantAware = tenantAware; + this.systemSecurityContext = systemSecurityContext; this.configurationKeyTenantRunner = new SecurityConfigurationKeyTenantRunner(); } @@ -53,9 +55,10 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe private final class SecurityConfigurationKeyTenantRunner implements TenantAware.TenantRunner { @Override public Boolean run() { + LOGGER.trace("retrieving configuration value for configuration key {}", getTenantConfigurationKey()); - return tenantConfigurationManagement.getConfigurationValue(getTenantConfigurationKey(), Boolean.class) - .getValue(); + return systemSecurityContext.runAsSystem(() -> tenantConfigurationManagement + .getConfigurationValue(getTenantConfigurationKey(), Boolean.class).getValue()); } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java index c1dd49e0a..c30f60711 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java @@ -45,8 +45,8 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro /** * Constructor. * - * @param systemManagement - * the system management service to retrieve configuration + * @param tenantConfigurationManagement + * the tenant management service to retrieve configuration * properties * @param controllerManagement * the controller management to retrieve the specific target @@ -54,11 +54,15 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro * @param tenantAware * the tenant aware service to get configuration for the specific * tenant + * @param systemSecurityContext + * the system security context to get access to tenant + * configuration */ public ControllerPreAuthenticateSecurityTokenFilter( final TenantConfigurationManagement tenantConfigurationManagement, - final ControllerManagement controllerManagement, final TenantAware tenantAware) { - super(tenantConfigurationManagement, tenantAware); + final ControllerManagement controllerManagement, final TenantAware tenantAware, + final SystemSecurityContext systemSecurityContext) { + super(tenantConfigurationManagement, tenantAware, systemSecurityContext); this.controllerManagement = controllerManagement; } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java index 95308d671..765589df4 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -39,16 +39,20 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra /** * Constructor. * - * @param systemManagement - * the system management service to retrieve configuration + * @param tenantConfigurationManagement + * the tenant management service to retrieve configuration * properties * @param tenantAware * the tenant aware service to get configuration for the specific * tenant + * @param systemSecurityContext + * the system security context to get access to tenant + * configuration */ public ControllerPreAuthenticatedGatewaySecurityTokenFilter( - final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware) { - super(tenantConfigurationManagement, tenantAware); + final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, + final SystemSecurityContext systemSecurityContext) { + super(tenantConfigurationManagement, tenantAware, systemSecurityContext); } @Override @@ -84,8 +88,12 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra public String run() { LOGGER.trace("retrieving configuration value for configuration key {}", TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY); - return tenantConfigurationManagement.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue(); + + return systemSecurityContext + .runAsSystem(() -> tenantConfigurationManagement + .getConfigurationValue( + TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, String.class) + .getValue()); } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java index 21289b71c..c74d9182a 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java @@ -56,18 +56,20 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont * @param caAuthorityNameHeader * the http-header which holds the ca-authority name of the * certificate - * @param systemManagement - * the system management service to retrieve configuration - * properties to check if the header authentication is enabled - * for this tenant + * @param tenantConfigurationManagement + * the tenant management service to retrieve configuration + * properties * @param tenantAware * the tenant aware service to get configuration for the specific * tenant + * @param systemSecurityContext + * the system security context to get access to tenant + * configuration */ public ControllerPreAuthenticatedSecurityHeaderFilter(final String caCommonNameHeader, final String caAuthorityNameHeader, final TenantConfigurationManagement tenantConfigurationManagement, - final TenantAware tenantAware) { - super(tenantConfigurationManagement, tenantAware); + final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) { + super(tenantConfigurationManagement, tenantAware, systemSecurityContext); this.caCommonNameHeader = caCommonNameHeader; this.sslIssuerHashBasicHeader = caAuthorityNameHeader; } From 4ca1bdf9ef303e8d28f4aef63b22781610276aa6 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 25 Feb 2016 09:42:38 +0100 Subject: [PATCH 29/42] fix tests by setting the SystemSecurityContext to prevent NPE in tests Signed-off-by: Michael Hirsch --- .../hawkbit/amqp/AmqpControllerAuthentfication.java | 3 +++ .../amqp/AmqpControllerAuthentficationTest.java | 9 +++++++-- .../hawkbit/security/SystemSecurityContext.java | 12 +++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java index c708ac0c7..b7570f185 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java @@ -153,4 +153,7 @@ public class AmqpControllerAuthentfication { this.tenantAware = tenantAware; } + void setSystemSecurityContext(final SystemSecurityContext systemSecurityContext) { + this.systemSecurityContext = systemSecurityContext; + } } diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java index e25afe490..19ecc22ca 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentficationTest.java @@ -26,6 +26,7 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SecurityProperties; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.junit.Before; import org.junit.Test; @@ -81,7 +82,8 @@ public class AmqpControllerAuthentficationTest { tenantConfigurationManagement = mock(TenantConfigurationManagement.class); authenticationManager.setTenantConfigurationManagement(tenantConfigurationManagement); - when(tenantConfigurationManagement.getConfigurationValue(any(), eq(Boolean.class))).thenReturn(CONFIG_VALUE_FALSE); + when(tenantConfigurationManagement.getConfigurationValue(any(), eq(Boolean.class))) + .thenReturn(CONFIG_VALUE_FALSE); final ControllerManagement controllerManagement = mock(ControllerManagement.class); when(controllerManagement.getSecurityTokenByControllerId(anyString())).thenReturn(CONTROLLLER_ID); @@ -89,7 +91,10 @@ public class AmqpControllerAuthentficationTest { amqpMessageHandlerService.setArtifactManagement(mock(ArtifactManagement.class)); - authenticationManager.setTenantAware(new SecurityContextTenantAware()); + final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(); + authenticationManager.setTenantAware(tenantAware); + final SystemSecurityContext systemSecurityContext = new SystemSecurityContext(tenantAware); + authenticationManager.setSystemSecurityContext(systemSecurityContext); authenticationManager.postConstruct(); amqpMessageHandlerService.setAuthenticationManager(authenticationManager); } 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 7e3dc8de7..334065a10 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 @@ -38,8 +38,18 @@ public class SystemSecurityContext { private static final Logger logger = LoggerFactory.getLogger(SystemSecurityContext.class); + private final TenantAware tenantAware; + + /** + * Autowired constructor. + * + * @param tenantAware + * the tenant aware bean to retrieve the current tenant + */ @Autowired - private TenantAware tenantAware; + public SystemSecurityContext(final TenantAware tenantAware) { + this.tenantAware = tenantAware; + } public T runAsSystem(final Callable callable) { final SecurityContext oldContext = SecurityContextHolder.getContext(); From d183322522481f0c6c0769d97e4cc98532122133 Mon Sep 17 00:00:00 2001 From: "Nonnenmacher Fabian (INST-ICM/BSV-AS)" Date: Fri, 26 Feb 2016 15:07:10 +0100 Subject: [PATCH 30/42] Changed caption from checkbox to tooltip Signed-off-by: Nonnenmacher Fabian --- .../PollingConfigurationView.java | 4 ++-- .../polling/DurationConfigField.java | 20 ++++++------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index e8ca6a61f..791d1a107 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -91,13 +91,13 @@ public class PollingConfigurationView extends BaseConfigurationView vLayout.addComponent(headerDisSetType); fieldPollTime = DurationConfigField.builder().caption(i18n.get("configuration.polling.time")) - .checkBoxLabel(i18n.get("configuration.polling.custom.value")).range(minDuration, maxDuration) + .checkBoxTooltip(i18n.get("configuration.polling.custom.value")).range(minDuration, maxDuration) .globalDuration(globalPollTime).tenantDuration(tenantPollTime).build(); fieldPollTime.addChangeListener(this); vLayout.addComponent(fieldPollTime); fieldPollingOverdueTime = DurationConfigField.builder().caption(i18n.get("configuration.polling.overduetime")) - .checkBoxLabel(i18n.get("configuration.polling.custom.value")).range(minDuration, maxDuration) + .checkBoxTooltip(i18n.get("configuration.polling.custom.value")).range(minDuration, maxDuration) .globalDuration(globalOverdueTime).tenantDuration(tenantOverdueTime).build(); fieldPollingOverdueTime.addChangeListener(this); vLayout.addComponent(fieldPollingOverdueTime); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index c311489e0..f6302750e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -4,16 +4,13 @@ import java.time.Duration; import java.util.ArrayList; import java.util.List; -import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationItem; -import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.ui.Alignment; import com.vaadin.ui.CheckBox; import com.vaadin.ui.GridLayout; -import com.vaadin.ui.Label; /** * The DurationConfigField consists of three vaadin fields. A {@link #Label} @@ -30,10 +27,9 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen private final CheckBox checkBox = new CheckBox(); private final DurationField durationField = new DurationField(); private Duration globalDuration; - private final Label labelCustomValue; private DurationConfigField() { - super(3, 2); + super(2, 2); this.addStyleName("duration-config-field"); this.setSpacing(true); @@ -43,11 +39,7 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen this.addComponent(checkBox, 0, 0); this.setComponentAlignment(checkBox, Alignment.MIDDLE_LEFT); - labelCustomValue = SPUIComponentProvider.getLabel("", SPUILabelDefinitions.SP_LABEL_SIMPLE); - this.addComponent(labelCustomValue, 1, 0); - this.setComponentAlignment(labelCustomValue, Alignment.MIDDLE_LEFT); - - this.addComponent(durationField, 2, 0); + this.addComponent(durationField, 1, 0); this.setComponentAlignment(durationField, Alignment.MIDDLE_LEFT); checkBox.addValueChangeListener(this); @@ -80,8 +72,8 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen this.setValue(tenantDuration); } - private void setCheckboxLabel(final String label) { - labelCustomValue.setValue(label); + private void setCheckBoxTooltip(final String label) { + checkBox.setDescription(label); } private void setAllowedRange(final Duration minimumDuration, final Duration maximumDuration) { @@ -148,8 +140,8 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen field = new DurationConfigField(); }; - public DurationConfigFieldBuilder checkBoxLabel(final String label) { - field.setCheckboxLabel(label); + public DurationConfigFieldBuilder checkBoxTooltip(final String label) { + field.setCheckBoxTooltip(label); return this; } From 05ce99bf3dc6310dab810cdae032c9140b6583c6 Mon Sep 17 00:00:00 2001 From: "Nonnenmacher Fabian (INST-ICM/BSV-AS)" Date: Mon, 29 Feb 2016 12:24:46 +0100 Subject: [PATCH 31/42] Added missing Headers, removed @Auther comment Signed-off-by: Nonnenmacher Fabian --- .../model/system/TenantConfigurationValueRequest.java | 8 ++++++++ .../model/system/TenantConfigurationValueRest.java | 9 +++++++++ .../ui/tenantconfiguration/BaseConfigurationView.java | 1 - .../ui/tenantconfiguration/PollingConfigurationView.java | 1 - 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java index 91a8820f1..b0ae6e546 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRequest.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.rest.resource.model.system; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java index cf4a487a4..5317264d4 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java @@ -1,3 +1,12 @@ +/** + * 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.rest.resource.model.system; import org.springframework.hateoas.ResourceSupport; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java index a3f313414..223017ccb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java @@ -9,7 +9,6 @@ import com.vaadin.ui.CustomComponent; * base class for all configuration views. This class implements the logic for * the handling of the * - * @author Fabian Nonnenmacher */ public abstract class BaseConfigurationView extends CustomComponent implements ConfigurationGroup { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 791d1a107..8575d1f89 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java @@ -22,7 +22,6 @@ import com.vaadin.ui.VerticalLayout; /** * View to configure the polling interval and the overdue time. * - * @author Fabian Nonnenmacher * */ @SpringComponent From ce6f40f512446a4c1245c3eb1901b8f18d04abba Mon Sep 17 00:00:00 2001 From: Nonnenmacher Fabian Date: Mon, 29 Feb 2016 12:52:24 +0100 Subject: [PATCH 32/42] Added FunctionalInterface annotation, which got lost during rebasing Signed-off-by: Nonnenmacher Fabian --- .../hawkbit/ui/tenantconfiguration/ConfigurationItem.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java index 746d52ca5..44408b343 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java @@ -26,6 +26,7 @@ public interface ConfigurationItem { * in configuration group. * */ + @FunctionalInterface interface ConfigurationItemChangeListener extends Serializable { /** * called to notify about configuration has been changed. From 0e9991b0a434344bd0b80114fe70eeb169ea06b7 Mon Sep 17 00:00:00 2001 From: "Nonnenmacher Fabian (INST-ICM/BSV-AS)" Date: Mon, 29 Feb 2016 14:28:44 +0100 Subject: [PATCH 33/42] Added missing licence header Signed-off-by: Nonnenmacher Fabian --- .../tenancy/configuration/DurationHelper.java | 8 +++++ ...nvalidTenantConfigurationKeyException.java | 8 +++++ .../TenantConfigurationBooleanValidator.java | 11 ++++++- ...ConfigurationPollingDurationValidator.java | 8 +++++ .../TenantConfigurationStringValidator.java | 9 ++++++ .../TenantConfigurationValidator.java | 8 +++++ ...TenantConfigurationValidatorException.java | 8 +++++ .../TenantConfigurationManagement.java | 8 +++++ .../model/TenantConfigurationValue.java | 8 +++++ .../TenantConfigurationManagementTest.java | 8 +++++ .../hawkbit/rest/resource/SystemMapper.java | 8 +++++ .../hawkbit/rest/resource/SystemResource.java | 8 +++++ .../resource/ConfigurationResourceTest.java | 8 +++++ .../BaseConfigurationView.java | 8 +++++ .../ConfigurationItem.java | 8 +++++ .../PollingConfigurationView.java | 8 +++++ .../polling/DurationConfigField.java | 8 +++++ .../polling/DurationField.java | 32 ++++++++++++------- 18 files changed, 159 insertions(+), 13 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java index 79f5305c5..52e616edc 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.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.tenancy.configuration; import java.time.Duration; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java index 49edd231c..dcc42065c 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.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.tenancy.configuration; import org.eclipse.hawkbit.exception.SpServerError; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java index 0a8840933..e0410c781 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java @@ -1,7 +1,16 @@ +/** + * 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.tenancy.configuration.validator; /** - * specific tenant configuration validator, which validates that the given value is a booleans. + * specific tenant configuration validator, which validates that the given value + * is a booleans. */ public class TenantConfigurationBooleanValidator implements TenantConfigurationValidator { diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java index 2dfd9b6c2..02ad148e3 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.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.tenancy.configuration.validator; import java.time.Duration; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java index c71744773..b29d5476e 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java @@ -1,3 +1,12 @@ +/** + * 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.tenancy.configuration.validator; /** diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java index 83a8686c4..0067fd041 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.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.tenancy.configuration.validator; /** diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java index 4ce509a46..dffc13dcb 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.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.tenancy.configuration.validator; import org.eclipse.hawkbit.exception.SpServerError; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 2697abf6e..8dbc7fa76 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.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.im.authentication.SpPermission.SpringEvalExpressions; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java index 48e1e2006..4752eeb4e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.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.model; /** diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java index 1fb41048f..1b6d2942f 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TenantConfigurationManagementTest.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 static org.fest.assertions.api.Assertions.assertThat; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java index 31d7ef062..0f8119b53 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemMapper.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.rest.resource; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java index cd4a0fa1f..9f2201868 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SystemResource.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.rest.resource; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.java index 5c359ea3f..39e571a2c 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/ConfigurationResourceTest.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.rest.resource; import static org.fest.assertions.api.Assertions.assertThat; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java index 223017ccb..559eeae02 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/BaseConfigurationView.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.tenantconfiguration; import java.util.ArrayList; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java index 44408b343..4cec944a8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.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.tenantconfiguration; import java.io.Serializable; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java index 8575d1f89..f956abe10 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/PollingConfigurationView.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.tenantconfiguration; import java.time.Duration; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index f6302750e..654ee729c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.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.tenantconfiguration.polling; import java.time.Duration; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java index f5b33354e..97d63d839 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.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.tenantconfiguration.polling; import java.text.ParseException; @@ -78,16 +86,16 @@ public class DurationField extends DateField { * ConversionException is thrown which marks the DurationField as invalid. */ @Override - protected Date handleUnparsableDateString(String value) throws ConversionException { + protected Date handleUnparsableDateString(final String value) throws ConversionException { try { return durationFormat.parse(value); - } catch (ParseException e1) { + } catch (final ParseException e1) { try { return additionalFormat.parse("000000".substring(value.length() <= 6 ? value.length() : 6) + value); - } catch (ParseException e2) { + } catch (final ParseException e2) { // if Parsing is not possible ConversionException is thrown } } @@ -95,13 +103,13 @@ public class DurationField extends DateField { } @Override - public void valueChange(Property.ValueChangeEvent event) { + public void valueChange(final Property.ValueChangeEvent event) { // do not delete this method, even when removing the code inside this // method. This method overwrites the super method, which is // necessary, that parsing works correctly on pressing enter key if (event.getProperty() instanceof DurationField) { - Date value = (Date) event.getProperty().getValue(); + final Date value = (Date) event.getProperty().getValue(); // setValue() calls valueChanged again, when the minimum is greater // than the maximum this can lead to an endless loop @@ -120,7 +128,7 @@ public class DurationField extends DateField { } @Override - public void validate(Date value) throws InvalidValueException { + public void validate(final Date value) throws InvalidValueException { super.validate(value); if (value != null && maximumDuration != null && compareTimeOfDates(value, maximumDuration) > 0) { @@ -138,7 +146,7 @@ public class DurationField extends DateField { * @param duration * duration, only values <= 23:59:59 are excepted */ - public void setDuration(@NotNull Duration duration) { + public void setDuration(@NotNull final Duration duration) { if (duration.compareTo(MAXIMUM_DURATION) > 0) { throw new IllegalArgumentException("The duaration has to be smaller than 23:59:59."); } @@ -163,7 +171,7 @@ public class DurationField extends DateField { * @param minimumDuration * minimum Duration, only values smaller 23:59:59 are excepted */ - public void setMinimumDuration(@NotNull Duration minimumDuration) { + public void setMinimumDuration(@NotNull final Duration minimumDuration) { if (minimumDuration.compareTo(MAXIMUM_DURATION) > 0) { throw new IllegalArgumentException("The minimum duaration has to be smaller than 23:59:59."); } @@ -176,7 +184,7 @@ public class DurationField extends DateField { * @param maximumDuration * maximumDuration, only values smaller 23:59:59 are excepted */ - public void setMaximumDuration(@NotNull Duration maximumDuration) { + public void setMaximumDuration(@NotNull final Duration maximumDuration) { if (maximumDuration.compareTo(MAXIMUM_DURATION) > 0) { throw new IllegalArgumentException("The maximum duaration has to be smaller than 23:59:59."); } @@ -212,9 +220,9 @@ public class DurationField extends DateField { * before the time of d2; and a value greater than 0 if the time of * d1 is after the time represented by d2. */ - private int compareTimeOfDates(Date d1, Date d2) { - LocalTime lt1 = LocalDateTime.ofInstant(d1.toInstant(), ZONEID_UTC).toLocalTime(); - LocalTime lt2 = LocalDateTime.ofInstant(d2.toInstant(), ZONEID_UTC).toLocalTime(); + private int compareTimeOfDates(final Date d1, final Date d2) { + final LocalTime lt1 = LocalDateTime.ofInstant(d1.toInstant(), ZONEID_UTC).toLocalTime(); + final LocalTime lt2 = LocalDateTime.ofInstant(d2.toInstant(), ZONEID_UTC).toLocalTime(); return lt1.compareTo(lt2); } From e791954e13b7711524ca9aa5763350aee097ee10 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Tue, 1 Mar 2016 10:31:30 +0100 Subject: [PATCH 34/42] Add a generic check for configuration validator Signed-off-by: SirWayne --- .../TenantConfigurationBooleanValidator.java | 7 ++----- ...tConfigurationPollingDurationValidator.java | 10 ++++++---- .../TenantConfigurationStringValidator.java | 7 ++----- .../TenantConfigurationValidator.java | 18 +++++++++++++++++- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java index e0410c781..8836d8578 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationBooleanValidator.java @@ -15,11 +15,8 @@ package org.eclipse.hawkbit.tenancy.configuration.validator; public class TenantConfigurationBooleanValidator implements TenantConfigurationValidator { @Override - public void validate(final Object tenantConfigurationValue) { - if (tenantConfigurationValue instanceof Boolean) { - return; - } - throw new TenantConfigurationValidatorException("The given configuration value is expected as a boolean."); + public Class validateToClass() { + return Boolean.class; } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java index 02ad148e3..61c914105 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java @@ -43,10 +43,7 @@ public class TenantConfigurationPollingDurationValidator implements TenantConfig @Override public void validate(final Object tenantConfigurationObject) { - if (!(tenantConfigurationObject instanceof String)) { - throw new TenantConfigurationValidatorException("The given configuration value is expected as a string."); - } - + TenantConfigurationValidator.super.validate(tenantConfigurationObject); final String tenantConfigurationString = (String) tenantConfigurationObject; final Duration tenantConfigurationValue; @@ -66,4 +63,9 @@ public class TenantConfigurationPollingDurationValidator implements TenantConfig durationHelper.durationToFormattedString(maxDuration))); } } + + @Override + public Class validateToClass() { + return String.class; + } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java index b29d5476e..fc427f4ac 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationStringValidator.java @@ -15,10 +15,7 @@ package org.eclipse.hawkbit.tenancy.configuration.validator; public class TenantConfigurationStringValidator implements TenantConfigurationValidator { @Override - public void validate(final Object tenantConfigurationValue) { - if (tenantConfigurationValue instanceof String) { - return; - } - throw new TenantConfigurationValidatorException("The given configuration value is expected as a String."); + public Class validateToClass() { + return String.class; } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java index 0067fd041..dccf515e6 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java @@ -22,5 +22,21 @@ public interface TenantConfigurationValidator { * @throws TenantConfigurationValidatorException * is thrown, when parameter is invalid. */ - void validate(Object tenantConfigurationValue) throws TenantConfigurationValidatorException; + default void validate(final Object tenantConfigurationValue) throws TenantConfigurationValidatorException { + if (tenantConfigurationValue != null + && validateToClass().isAssignableFrom(tenantConfigurationValue.getClass())) { + return; + } + throw new TenantConfigurationValidatorException( + "The given configuration value is expected as a " + validateToClass().getSimpleName()); + } + + /** + * Return the generic class to check the object + * + * @return the class to check the value + */ + default Class validateToClass() { + return Object.class; + } } From 9646e1eabc29c670a382f217e0c1306cbce49664 Mon Sep 17 00:00:00 2001 From: "Nonnenmacher Fabian (INST-ICM/BSV-AS)" Date: Fri, 4 Mar 2016 12:02:59 +0100 Subject: [PATCH 35/42] Fixed review findings --- .../exception/SpServerRtException.java | 3 +- .../configuration/TenantConfigurationKey.java | 42 +++++++------ ...ConfigurationPollingDurationValidator.java | 9 +-- ...lerPreAuthenticateSecurityTokenFilter.java | 4 +- ...thenticatedGatewaySecurityTokenFilter.java | 5 ++ ...rPreAuthenticatedSecurityHeaderFilter.java | 10 +-- .../TenantConfigurationManagement.java | 25 ++++---- .../hawkbit/repository/model/TargetInfo.java | 38 +++++------ .../model/TenantConfigurationValue.java | 14 ++--- .../system/TenantConfigurationValueRest.java | 15 +++-- .../AuthenticationConfigurationView.java | 63 ++++++------------- .../ConfigurationItem.java | 5 +- .../TenantConfigurationDashboardView.java | 36 ++++------- ...AuthenticationTenantConfigurationItem.java | 23 +------ ...yTokenAuthenticationConfigurationItem.java | 5 +- .../polling/DurationConfigField.java | 27 ++++---- .../polling/DurationField.java | 25 ++++---- 17 files changed, 152 insertions(+), 197 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java index 46ee644ce..ba691bb5f 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java @@ -75,8 +75,7 @@ public abstract class SpServerRtException extends RuntimeException { } /** - * - * @return the SpServerError + * @return the SpServerError which is wrapped by this exception */ public SpServerError getError() { return error; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index 1f5481dc0..68c68d0da 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.tenancy.configuration; import java.util.Arrays; -import java.util.NoSuchElementException; +import java.util.Optional; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationPollingDurationValidator; @@ -84,10 +84,18 @@ public enum TenantConfigurationKey { private final Class validator; /** + * * @param key * the property key name - * @param allowedValues + * @param defaultKeyName * the allowed values for this specific key + * @param dataType + * the class of the property + * @param defaultValue + * value which should be returned, in case there is no value in + * the database + * @param validator + * Validator which validates, that property is of correct format */ private TenantConfigurationKey(final String key, final String defaultKeyName, final Class dataType, final String defaultValue, final Class validator) { @@ -96,7 +104,6 @@ public enum TenantConfigurationKey { this.defaultKeyName = defaultKeyName; this.defaultValue = defaultValue; this.validator = validator; - } /** @@ -138,17 +145,14 @@ public enum TenantConfigurationKey { * @param value * which will be validated * @throws TenantConfigurationValidatorException - * is thrown when object is invalid. + * is thrown, when object is invalid */ - public void validate(final ApplicationContext context, final Object value) - throws TenantConfigurationValidatorException { - final TenantConfigurationValidator createBean = context.getAutowireCapableBeanFactory().createBean(validator); + public void validate(final ApplicationContext context, final Object value) { + final TenantConfigurationValidator createdBean = context.getAutowireCapableBeanFactory().createBean(validator); try { - createBean.validate(value); - } catch (final TenantConfigurationValidatorException ex) { - throw ex; + createdBean.validate(value); } finally { - context.getAutowireCapableBeanFactory().destroyBean(createBean); + context.getAutowireCapableBeanFactory().destroyBean(createdBean); } } @@ -156,17 +160,15 @@ public enum TenantConfigurationKey { * @param keyName * name of the TenantConfigurationKey * @return the TenantConfigurationKey with the name keyName - * @throws InvalidTenantConfigurationKeyException - * if there is no TenantConfigurationKey with the name keyName */ - public static TenantConfigurationKey fromKeyName(final String keyName) - throws InvalidTenantConfigurationKeyException { + public static TenantConfigurationKey fromKeyName(final String keyName) { - try { - return Arrays.stream(TenantConfigurationKey.values()).filter(conf -> conf.getKeyName().equals(keyName)) - .findFirst().get(); - } catch (final NoSuchElementException e) { - throw new InvalidTenantConfigurationKeyException("The given configuration key name does not exist."); + final Optional optKey = Arrays.stream(TenantConfigurationKey.values()) + .filter(conf -> conf.getKeyName().equals(keyName)).findFirst(); + + if (optKey.isPresent()) { + return optKey.get(); } + throw new InvalidTenantConfigurationKeyException("The given configuration key name does not exist."); } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java index 02ad148e3..53dd59cd4 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java @@ -16,13 +16,12 @@ import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.springframework.beans.factory.annotation.Autowired; /** - * specific tenant configuration validator, which validates that the given value - * is a String in the correct duration format.. + * This class is used to validate, that the property is a String and that it is + * in the correct duration format. + * */ public class TenantConfigurationPollingDurationValidator implements TenantConfigurationValidator { - // private final ControllerPollProperties properties; - private final DurationHelper durationHelper = new DurationHelper(); private final Duration minDuration; @@ -35,8 +34,6 @@ public class TenantConfigurationPollingDurationValidator implements TenantConfig */ @Autowired public TenantConfigurationPollingDurationValidator(final ControllerPollProperties properties) { - // this.properties = properties; - minDuration = durationHelper.formattedStringToDuration(properties.getMinPollingTime()); maxDuration = durationHelper.formattedStringToDuration(properties.getMaxPollingTime()); } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java index c7106e6dd..1eb155b9a 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java @@ -35,7 +35,7 @@ public class HttpControllerPreAuthenticateSecurityTokenFilter extends AbstractHt /** * Constructor. * - * @param systemManagement + * @param tenantConfigurationManagement * the system management service to retrieve configuration * properties * @param tenantAware @@ -44,6 +44,8 @@ public class HttpControllerPreAuthenticateSecurityTokenFilter extends AbstractHt * @param controllerManagement * the controller management to retrieve the specific target * security token to verify + * @param systemSecurityContext + * the system security context */ public HttpControllerPreAuthenticateSecurityTokenFilter( final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java index 3d32811ce..f97dde608 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -27,12 +27,17 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter /** * Constructor. * + * @param tenantConfigurationManagement + * the system management service to retrieve configuration + * properties * @param systemManagement * the system management service to retrieve configuration * properties * @param tenantAware * the tenant aware service to get configuration for the specific * tenant + * @param systemSecurityContext + * * @param systemSecurityContext the system security context */ public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter( final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java index 58e6be4a9..162e2688d 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java @@ -35,13 +35,15 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract * @param caAuthorityNameHeader * the http-header which holds the ca-authority name of the * certificate - * @param systemManagement - * the system management service to retrieve configuration - * properties to check if the header authentication is enabled - * for this tenant + * @param tenantConfigurationManagement + * the tenant configuration management service to retrieve + * configuration properties to check if the header authentication + * is enabled for this tenant * @param tenantAware * the tenant aware service to get configuration for the specific * tenant + * @param systemSecurityContext + * the system security context */ public HttpControllerPreAuthenticatedSecurityHeaderFilter(final String caCommonNameHeader, final String caAuthorityNameHeader, final TenantConfigurationManagement tenantConfigurationManagement, diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 8dbc7fa76..3dbd6159e 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -84,7 +84,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR + SpringEvalExpressions.IS_SYSTEM_CODE) public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, - final Class propertyType) throws TenantConfigurationValidatorException { + final Class propertyType) { if (!configurationKey.getDataType().isAssignableFrom(propertyType)) { throw new TenantConfigurationValidatorException( @@ -130,8 +130,7 @@ public class TenantConfigurationManagement implements EnvironmentAware { * {@code propertyType} */ @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) - public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey) - throws TenantConfigurationValidatorException { + public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey) { return getConfigurationValue(configurationKey, configurationKey.getDataType()); } @@ -156,8 +155,8 @@ public class TenantConfigurationManagement implements EnvironmentAware { * {@code propertyType} */ @PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) - public T getGlobalConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) - throws TenantConfigurationValidatorException { + public T getGlobalConfigurationValue(final TenantConfigurationKey configurationKey, + final Class propertyType) { if (!configurationKey.getDataType().isAssignableFrom(propertyType)) { throw new TenantConfigurationValidatorException( @@ -167,10 +166,11 @@ public class TenantConfigurationManagement implements EnvironmentAware { final T valueInProperties = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType); - if (valueInProperties != null) { - return valueInProperties; + if (valueInProperties == null) { + return conversionService.convert(configurationKey.getDefaultValue(), propertyType); } - return conversionService.convert(configurationKey.getDefaultValue(), propertyType); + + return valueInProperties; } /** @@ -206,14 +206,11 @@ public class TenantConfigurationManagement implements EnvironmentAware { TenantConfiguration tenantConfiguration = tenantConfigurationRepository .findByKey(configurationKey.getKeyName()); - if (tenantConfiguration != null) - { - tenantConfiguration.setValue(value.toString()); - } else - - { + if (tenantConfiguration == null) { tenantConfiguration = new TenantConfiguration(configurationKey.getKeyName(), value.toString()); + } else { + tenantConfiguration.setValue(value.toString()); } final TenantConfiguration updatedTenantConfiguration = tenantConfigurationRepository.save(tenantConfiguration); diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index 2f221948f..06b02343f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -320,22 +320,21 @@ public class TargetInfo implements Persistable, Serializable { * before this method returns {@code null} */ public PollStatus getPollStatus() { - if (lastTargetQuery != null) { - final Duration pollTime = durationHelper.formattedStringToDuration(TenantConfigurationManagement - .getInstance().getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class) - .getValue()); - final Duration overdueTime = durationHelper - .formattedStringToDuration(TenantConfigurationManagement.getInstance() - .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) - .getValue()); - final LocalDateTime currentDate = LocalDateTime.now(); - final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), - ZoneId.systemDefault()); - final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); - final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); - return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); + if (lastTargetQuery == null) { + return null; } - return null; + + final Duration pollTime = durationHelper.formattedStringToDuration(TenantConfigurationManagement.getInstance() + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); + final Duration overdueTime = durationHelper.formattedStringToDuration(TenantConfigurationManagement + .getInstance().getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) + .getValue()); + final LocalDateTime currentDate = LocalDateTime.now(); + final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), + ZoneId.systemDefault()); + final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); + final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); + return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); } /** @@ -378,23 +377,14 @@ public class TargetInfo implements Persistable, Serializable { return lastPollDate; } - /** - * @return the nextPollDate - */ public LocalDateTime getNextPollDate() { return nextPollDate; } - /** - * @return the overdueDate - */ public LocalDateTime getOverdueDate() { return overdueDate; } - /** - * @return the current date - */ public LocalDateTime getCurrentDate() { return currentDate; } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java index 4752eeb4e..d8483e12f 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TenantConfigurationValue.java @@ -16,16 +16,16 @@ package org.eclipse.hawkbit.repository.model; */ public class TenantConfigurationValue { + private T value; + private Long lastModifiedAt; + private String lastModifiedBy; + private Long createdAt; + private String createdBy; + private boolean isGlobal = true; + private TenantConfigurationValue() { } - private T value = null; - private boolean isGlobal = true; - private Long lastModifiedAt = null; - private String lastModifiedBy = null; - private Long createdAt = null; - private String createdBy = null; - /** * Gets the value. * diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java index 5317264d4..47dcfebe0 100644 --- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/system/TenantConfigurationValueRest.java @@ -15,20 +15,25 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +/** + * A json annotated rest model for a tenant configuration value to RESTful API + * representation. + * + */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class TenantConfigurationValueRest extends ResourceSupport { @JsonInclude(Include.ALWAYS) - private Object value = null; + private Object value; @JsonInclude(Include.ALWAYS) private boolean isGlobal = true; - private Long lastModifiedAt = null; - private String lastModifiedBy = null; - private Long createdAt = null; - private String createdBy = null; + private Long lastModifiedAt; + private String lastModifiedBy; + private Long createdAt; + private String createdBy; public Object getValue() { return value; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java index e440251c9..94e852813 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java @@ -39,14 +39,8 @@ import com.vaadin.ui.VerticalLayout; public class AuthenticationConfigurationView extends BaseConfigurationView implements ConfigurationGroup, ConfigurationItem.ConfigurationItemChangeListener, ValueChangeListener { - /** - * - */ private static final String DIST_CHECKBOX_STYLE = "dist-checkbox-style"; - /** - * - */ private static final long serialVersionUID = 1L; @Autowired @@ -119,13 +113,6 @@ public class AuthenticationConfigurationView extends BaseConfigurationView setCompositionRoot(rootPanel); } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.hawkbit.server.ui.tenantconfiguration.ConfigurationGroup#save - * () - */ @Override public void save() { certificateAuthenticationConfigurationItem.save(); @@ -133,13 +120,6 @@ public class AuthenticationConfigurationView extends BaseConfigurationView gatewaySecurityTokenAuthenticationConfigurationItem.save(); } - /* - * (non-Javadoc) - * - * @see - * org.eclipse.hawkbit.server.ui.tenantconfiguration.ConfigurationGroup#undo - * () - */ @Override public void undo() { certificateAuthenticationConfigurationItem.undo(); @@ -155,37 +135,32 @@ public class AuthenticationConfigurationView extends BaseConfigurationView notifyConfigurationChanged(); } - /* - * (non-Javadoc) - * - * @see com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin. - * data.Property. ValueChangeEvent) - */ @Override public void valueChange(final ValueChangeEvent event) { - if (event.getProperty() instanceof CheckBox) { - notifyConfigurationChanged(); + if (!(event.getProperty() instanceof CheckBox)) { + return; + } - CheckBox checkBox = (CheckBox) event.getProperty(); - AuthenticationConfigurationItem configurationItem = null; + notifyConfigurationChanged(); - if (checkBox == gatewaySecTokenCheckBox) { - configurationItem = gatewaySecurityTokenAuthenticationConfigurationItem; - } else if (checkBox == targetSecTokenCheckBox) { - configurationItem = targetSecurityTokenAuthenticationConfigurationItem; - } else if (checkBox == certificateAuthCheckbox) { - configurationItem = certificateAuthenticationConfigurationItem; - } else { - return; - } + final CheckBox checkBox = (CheckBox) event.getProperty(); + AuthenticationConfigurationItem configurationItem; - if (checkBox.getValue()) { - configurationItem.configEnable(); - } else { - configurationItem.configDisable(); - } + if (checkBox == gatewaySecTokenCheckBox) { + configurationItem = gatewaySecurityTokenAuthenticationConfigurationItem; + } else if (checkBox == targetSecTokenCheckBox) { + configurationItem = targetSecurityTokenAuthenticationConfigurationItem; + } else if (checkBox == certificateAuthCheckbox) { + configurationItem = certificateAuthenticationConfigurationItem; + } else { + return; + } + if (checkBox.getValue()) { + configurationItem.configEnable(); + } else { + configurationItem.configDisable(); } } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java index 4cec944a8..142de0abb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/ConfigurationItem.java @@ -10,6 +10,9 @@ package org.eclipse.hawkbit.ui.tenantconfiguration; import java.io.Serializable; +/** + * represents an configurationItem, which can be modified by the user + */ public interface ConfigurationItem { /** @@ -41,4 +44,4 @@ public interface ConfigurationItem { */ void configurationHasChanged(); } -} \ No newline at end of file +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java index d98aa8916..4b7fe515e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java @@ -44,8 +44,7 @@ import com.vaadin.ui.VerticalLayout; */ @SpringView(name = TenantConfigurationDashboardView.VIEW_NAME, ui = HawkbitUI.class) @ViewScope -public class TenantConfigurationDashboardView extends CustomComponent - implements View, ConfigurationItemChangeListener { +public class TenantConfigurationDashboardView extends CustomComponent implements View, ConfigurationItemChangeListener { public static final String VIEW_NAME = "spSystemConfig"; private static final long serialVersionUID = 1L; @@ -68,7 +67,7 @@ public class TenantConfigurationDashboardView extends CustomComponent private Button saveConfigurationBtn; private Button undoConfigurationBtn; - private List configurationViews = new ArrayList(); + private final List configurationViews = new ArrayList(); /** * init method adds all Configuration Views to the list of Views. @@ -91,9 +90,7 @@ public class TenantConfigurationDashboardView extends CustomComponent rootLayout.setMargin(true); rootLayout.setSpacing(true); - configurationViews.forEach(view -> { - rootLayout.addComponent(view); - }); + configurationViews.forEach(view -> rootLayout.addComponent(view)); final HorizontalLayout buttonContent = saveConfigurationButtonsLayout(); rootLayout.addComponent(buttonContent); @@ -101,9 +98,7 @@ public class TenantConfigurationDashboardView extends CustomComponent rootPanel.setContent(rootLayout); setCompositionRoot(rootPanel); - configurationViews.forEach(view -> { - view.addChangeListener(this); - }); + configurationViews.forEach(view -> view.addChangeListener(this)); } private HorizontalLayout saveConfigurationButtonsLayout() { @@ -132,23 +127,18 @@ public class TenantConfigurationDashboardView extends CustomComponent private void saveConfiguration() { - boolean isUserInputValid = configurationViews.stream().allMatch(confView -> { - return confView.isUserInputValid(); - }); + final boolean isUserInputValid = configurationViews.stream().allMatch(confView -> confView.isUserInputValid()); - if (isUserInputValid) { - configurationViews.forEach(confView -> { - confView.save(); - }); - - // More methods - saveConfigurationBtn.setEnabled(false); - undoConfigurationBtn.setEnabled(false); - uINotification.displaySuccess(i18n.get("notification.configuration.save.successful")); - - } else { + if (!isUserInputValid) { uINotification.displayValidationError(i18n.get("notification.configuration.save.notpossible")); + return; } + configurationViews.forEach(confView -> confView.save()); + + // More methods + saveConfigurationBtn.setEnabled(false); + undoConfigurationBtn.setEnabled(false); + uINotification.displaySuccess(i18n.get("notification.configuration.save.successful")); } private void undoConfiguration() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java index feb7e772c..0907ebf9e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/AbstractAuthenticationTenantConfigurationItem.java @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import com.vaadin.ui.VerticalLayout; /** - * Ab abstract authentication configuration item. + * abstract authentication configuration item. * * * @@ -28,9 +28,6 @@ import com.vaadin.ui.VerticalLayout; abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLayout implements AuthenticationConfigurationItem { - /** - * - */ private static final long serialVersionUID = 1L; private final TenantConfigurationKey configurationKey; @@ -59,17 +56,9 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay addComponent(SPUIComponentProvider.getLabel(labelText, SPUILabelDefinitions.SP_LABEL_SIMPLE)); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.tenantconfiguration. - * TenantConfigurationItem# isConfigEnabled() - */ @Override public boolean isConfigEnabled() { - final boolean b = tenantConfigurationManagement.getConfigurationValue(configurationKey, Boolean.class) - .getValue(); - return b; + return tenantConfigurationManagement.getConfigurationValue(configurationKey, Boolean.class).getValue(); } /** @@ -90,14 +79,6 @@ abstract class AbstractAuthenticationTenantConfigurationItem extends VerticalLay configurationChangeListeners.forEach(listener -> listener.configurationHasChanged()); } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.ui.tenantconfiguration. - * TenantConfigurationItem# addConfigurationChangeListener - * (hawkbit.server.ui.tenantconfiguration.TenantConfigurationItem. - * TenantConfigurationChangeListener) - */ @Override public void addChangeListener(final ConfigurationItemChangeListener listener) { configurationChangeListeners.add(listener); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java index 616e64769..42e50da2c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/authentication/TargetSecurityTokenAuthenticationConfigurationItem.java @@ -87,9 +87,10 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract @Override public void save() { - if (configurationEnabledChange) { - getTenantConfigurationManagement().addOrUpdateConfiguration(getConfigurationKey(), configurationEnabled); + if (!configurationEnabledChange) { + return; } + getTenantConfigurationManagement().addOrUpdateConfiguration(getConfigurationKey(), configurationEnabled); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index 654ee729c..83273df0a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -56,14 +56,18 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen @Override public void valueChange(final ValueChangeEvent event) { - if (event.getProperty() == checkBox) { - if (checkBox.getValue()) { - durationField.setEnabled(true); - } else { - durationField.setDuration(globalDuration); - durationField.setEnabled(false); - } + if (event.getProperty() != checkBox) { + return; } + + durationField.setEnabled(checkBox.getValue()); + + if (!checkBox.getValue()) { + durationField.setDuration(globalDuration); + } + + durationField.setEnabled(false); + notifyConfigurationChanged(); } @@ -102,11 +106,12 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen checkBox.setValue(false); durationField.setDuration(globalDuration); durationField.setEnabled(false); - } else { - checkBox.setValue(true); - durationField.setDuration(tenantDuration); - durationField.setEnabled(true); + return; } + + checkBox.setValue(true); + durationField.setDuration(tenantDuration); + durationField.setEnabled(true); } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java index 97d63d839..d511e275e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationField.java @@ -108,21 +108,22 @@ public class DurationField extends DateField { // method. This method overwrites the super method, which is // necessary, that parsing works correctly on pressing enter key - if (event.getProperty() instanceof DurationField) { - final Date value = (Date) event.getProperty().getValue(); + if (!(event.getProperty() instanceof DurationField)) { + return; + } + final Date value = (Date) event.getProperty().getValue(); - // setValue() calls valueChanged again, when the minimum is greater - // than the maximum this can lead to an endless loop - if (value != null && minimumDuration != null && maximumDuration != null - && minimumDuration.before(maximumDuration)) { + // setValue() calls valueChanged again, when the minimum is greater + // than the maximum this can lead to an endless loop + if (value != null && minimumDuration != null && maximumDuration != null + && minimumDuration.before(maximumDuration)) { - if (compareTimeOfDates(value, maximumDuration) > 0) { - ((DateField) event.getProperty()).setValue(maximumDuration); - } + if (compareTimeOfDates(value, maximumDuration) > 0) { + ((DateField) event.getProperty()).setValue(maximumDuration); + } - if (compareTimeOfDates(minimumDuration, value) > 0) { - ((DateField) event.getProperty()).setValue(minimumDuration); - } + if (compareTimeOfDates(minimumDuration, value) > 0) { + ((DateField) event.getProperty()).setValue(minimumDuration); } } } From a4cc3df0923d9af8f74d70539da4e3c5527dab9a Mon Sep 17 00:00:00 2001 From: SirWayne Date: Wed, 9 Mar 2016 15:36:59 +0100 Subject: [PATCH 36/42] Fix test properties Signed-off-by: SirWayne --- .../java/org/eclipse/hawkbit/HawkbitServerProperties.java | 2 ++ .../TenantConfigurationPollingDurationValidator.java | 3 ++- .../hawkbit/amqp/AmqpControllerAuthenticationTest.java | 6 +++++- ...ontrollerPreAuthenticatedGatewaySecurityTokenFilter.java | 3 --- .../test/java/org/eclipse/hawkbit/TestConfiguration.java | 2 +- .../ui/tenantconfiguration/polling/DurationConfigField.java | 3 --- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java index 878965102..633e6eaf9 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java @@ -9,11 +9,13 @@ package org.eclipse.hawkbit; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; /** * Properties for the server e.g. the server's URL which must be configured. * */ +@Component @ConfigurationProperties("hawkbit.server") public class HawkbitServerProperties { /** diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java index ea8703dcf..9696ac34c 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationPollingDurationValidator.java @@ -29,6 +29,8 @@ public class TenantConfigurationPollingDurationValidator implements TenantConfig private final Duration maxDuration; /** + * Constructor. + * * @param properties * property accessor for poll configuration */ @@ -46,7 +48,6 @@ public class TenantConfigurationPollingDurationValidator implements TenantConfig final Duration tenantConfigurationValue; try { tenantConfigurationValue = durationHelper.formattedStringToDuration(tenantConfigurationString); - } catch (final DateTimeParseException ex) { throw new TenantConfigurationValidatorException( String.format("The given configuration value is expected as a string in the format %s.", 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 df96834aa..66527727a 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 @@ -27,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.security.DdiSecurityProperties; import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp; import org.eclipse.hawkbit.security.SecurityContextTenantAware; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.junit.Before; import org.junit.Test; @@ -93,7 +94,10 @@ public class AmqpControllerAuthenticationTest { authenticationManager.setControllerManagement(controllerManagement); amqpMessageHandlerService.setArtifactManagement(mock(ArtifactManagement.class)); - authenticationManager.setTenantAware(new SecurityContextTenantAware()); + final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(); + authenticationManager.setTenantAware(tenantAware); + final SystemSecurityContext systemSecurityContext = new SystemSecurityContext(tenantAware); + authenticationManager.setSystemSecurityContext(systemSecurityContext); authenticationManager.postConstruct(); amqpMessageHandlerService.setAuthenticationManager(authenticationManager); } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java index f97dde608..930c66dca 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -30,9 +30,6 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter * @param tenantConfigurationManagement * the system management service to retrieve configuration * properties - * @param systemManagement - * the system management service to retrieve configuration - * properties * @param tenantAware * the tenant aware service to get configuration for the specific * tenant diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java index 706cb4479..e2838d866 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java @@ -47,7 +47,7 @@ import com.mongodb.MongoClientOptions; */ @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true) -@EnableConfigurationProperties({ DdiSecurityProperties.class, ControllerPollProperties.class }) +@EnableConfigurationProperties({ DdiSecurityProperties.class }) @Profile("test") public class TestConfiguration implements AsyncConfigurer { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index 83273df0a..ee2ccec44 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -59,15 +59,12 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen if (event.getProperty() != checkBox) { return; } - durationField.setEnabled(checkBox.getValue()); if (!checkBox.getValue()) { durationField.setDuration(globalDuration); } - durationField.setEnabled(false); - notifyConfigurationChanged(); } From 89431feb8eaa7b74888562dd064ef9d0f1295f0f Mon Sep 17 00:00:00 2001 From: SirWayne Date: Wed, 9 Mar 2016 16:26:33 +0100 Subject: [PATCH 37/42] Remove @Component from properties which is loaded by the autoconfig module, because then will be 2 beans created Signed-off-by: SirWayne --- .../main/java/org/eclipse/hawkbit/HawkbitServerProperties.java | 2 -- .../src/test/java/org/eclipse/hawkbit/TestConfiguration.java | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java index 633e6eaf9..878965102 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java @@ -9,13 +9,11 @@ package org.eclipse.hawkbit; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; /** * Properties for the server e.g. the server's URL which must be configured. * */ -@Component @ConfigurationProperties("hawkbit.server") public class HawkbitServerProperties { /** diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java index e2838d866..70372fac2 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java @@ -47,7 +47,7 @@ import com.mongodb.MongoClientOptions; */ @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true) -@EnableConfigurationProperties({ DdiSecurityProperties.class }) +@EnableConfigurationProperties({ HawkbitServerProperties.class, DdiSecurityProperties.class }) @Profile("test") public class TestConfiguration implements AsyncConfigurer { From e47d540eb5cc7f6c6158bb89f59e57c60aa4beb4 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Wed, 9 Mar 2016 16:26:33 +0100 Subject: [PATCH 38/42] Fix event listening for duration field Signed-off-by: SirWayne --- .../org/eclipse/hawkbit/HawkbitServerProperties.java | 2 -- .../java/org/eclipse/hawkbit/TestConfiguration.java | 2 +- .../polling/DurationConfigField.java | 12 ++++-------- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java index 633e6eaf9..878965102 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/HawkbitServerProperties.java @@ -9,13 +9,11 @@ package org.eclipse.hawkbit; import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.stereotype.Component; /** * Properties for the server e.g. the server's URL which must be configured. * */ -@Component @ConfigurationProperties("hawkbit.server") public class HawkbitServerProperties { /** diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java index e2838d866..70372fac2 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/TestConfiguration.java @@ -47,7 +47,7 @@ import com.mongodb.MongoClientOptions; */ @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true) -@EnableConfigurationProperties({ DdiSecurityProperties.class }) +@EnableConfigurationProperties({ HawkbitServerProperties.class, DdiSecurityProperties.class }) @Profile("test") public class TestConfiguration implements AsyncConfigurer { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index ee2ccec44..8cefc15fa 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -26,7 +26,7 @@ import com.vaadin.ui.GridLayout; * duration in the DurationField or he can configure using the global duration * by changing the CheckBox. */ -public class DurationConfigField extends GridLayout implements ValueChangeListener, ConfigurationItem { +public class DurationConfigField extends GridLayout implements ConfigurationItem { private static final long serialVersionUID = 1L; @@ -50,15 +50,11 @@ public class DurationConfigField extends GridLayout implements ValueChangeListen this.addComponent(durationField, 1, 0); this.setComponentAlignment(durationField, Alignment.MIDDLE_LEFT); - checkBox.addValueChangeListener(this); - durationField.addValueChangeListener(this); + checkBox.addValueChangeListener(event->checkBoxChange()); + durationField.addValueChangeListener(event->notifyConfigurationChanged()); } - @Override - public void valueChange(final ValueChangeEvent event) { - if (event.getProperty() != checkBox) { - return; - } + private void checkBoxChange() { durationField.setEnabled(checkBox.getValue()); if (!checkBox.getValue()) { From 57c722ea11b0f9ba858fba07254a60164885c3f9 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 14 Mar 2016 15:13:51 +0100 Subject: [PATCH 39/42] Remove the controller properties for polling time and overdue time and use the new tenant configuration management, which handle the tenant specific polling time. Signed-off-by: SirWayne --- .../hawkbit/ControllerPollProperties.java | 24 ++++--------------- .../hawkbit/controller/RootController.java | 20 ++++++++-------- .../controller/RootControllerTest.java | 14 +++++++++++ 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java index 6812afbbd..6f64c1092 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java @@ -23,37 +23,21 @@ public class ControllerPollProperties { * Recommended target polling time for DDI API. Final choice is up to the * target. */ - private String pollingTime = "00:05:00"; + private String pollingTime; /** * Assumed time frame where the target is considered overdue when no DDI * polling has been registered by the update server. */ - private String pollingOverdueTime = "00:05:00"; + private String pollingOverdueTime; private String maxPollingTime = "23:59:00"; private String minPollingTime = "00:00:30"; - public String getPollingTime() { - return pollingTime; - } - - public void setPollingTime(final String pollingTime) { - this.pollingTime = pollingTime; - } - - public String getPollingOverdueTime() { - return pollingOverdueTime; - } - - public void setPollingOverdueTime(final String pollingOverdue) { - this.pollingOverdueTime = pollingOverdue; - } - public String getMaxPollingTime() { return maxPollingTime; } - public void setMaxPollingTime(String maxPollingTime) { + public void setMaxPollingTime(final String maxPollingTime) { this.maxPollingTime = maxPollingTime; } @@ -61,7 +45,7 @@ public class ControllerPollProperties { return minPollingTime; } - public void setMinPollingTime(String minPollingTime) { + public void setMinPollingTime(final String minPollingTime) { this.minPollingTime = minPollingTime; } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java index 6928ee7b5..338ab689e 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java @@ -15,7 +15,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; -import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; import org.eclipse.hawkbit.cache.CacheWriteNotify; import org.eclipse.hawkbit.controller.model.ActionFeedback; @@ -31,6 +30,7 @@ import org.eclipse.hawkbit.controller.model.Result.FinalResult; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; @@ -43,6 +43,7 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; import org.eclipse.hawkbit.tenancy.TenantAware; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.util.IpUtil; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; @@ -77,8 +78,6 @@ public class RootController { private static final Logger LOG = LoggerFactory.getLogger(RootController.class); private static final String GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET = "given action ({}) is not assigned to given target ({})."; - private static final String SP_SERVER_CONFIG_PREFIX = "hawkbit.server."; - @Autowired private ControllerManagement controllerManagement; @@ -88,15 +87,15 @@ public class RootController { @Autowired private ArtifactManagement artifactManagement; - @Autowired - private ControllerPollProperties controllerPollProperties; - @Autowired private CacheWriteNotify cacheWriteNotify; @Autowired private TenantAware tenantAware; + @Autowired + private TenantConfigurationManagement tenantConfigurationManagement; + @Autowired private HawkbitSecurityProperties securityProperties; @@ -154,10 +153,11 @@ public class RootController { IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader())); } - return new ResponseEntity<>( - DataConversionHelper.fromTarget(target, controllerManagement.findActionByTargetAndActive(target), - controllerPollProperties.getPollingTime(), tenantAware), - HttpStatus.OK); + final String pollingTime = tenantConfigurationManagement + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue(); + + return new ResponseEntity<>(DataConversionHelper.fromTarget(target, + controllerManagement.findActionByTargetAndActive(target), pollingTime, tenantAware), HttpStatus.OK); } /** diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java index 45bf5755b..6a1ee73fc 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java @@ -34,6 +34,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.rest.resource.JsonBuilder; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.util.IpUtil; import org.junit.Test; import org.springframework.hateoas.MediaTypes; @@ -133,6 +134,19 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB { .andExpect(status().isMethodNotAllowed()); } + @Test + @Description("Ensures that tenant polling time, which is save in the db, exists.") + public void testModifyGloablPollingTime() throws Exception { + tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, + "00:02:00"); + + mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)) + .andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00"))); + + } + @Test @Description("Ensures that etag check results in not modified response if provided etag by client is identical to entity in repository.") public void rootRsNotModified() throws Exception { From 4c282d8ee3551a5e1de6ca5a303780b08769a07a Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 14 Mar 2016 15:39:01 +0100 Subject: [PATCH 40/42] Documented differences between system wide properties and the veritable by tenant --- .../hawkbit/ControllerPollProperties.java | 22 +++++++----- .../configuration/TenantConfigurationKey.java | 34 ++++++------------- 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java index 6f64c1092..c923963d2 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/ControllerPollProperties.java @@ -8,11 +8,19 @@ */ package org.eclipse.hawkbit; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.EnvironmentAware; import org.springframework.stereotype.Component; /** - * Defines the polling time for the controllers in HH:MM:SS notation. + * Defines global configuration for the controllers/clients on the provisioning + * targets/devices. + * + * + * Note: many of the controller related properties can be overridden on tenant + * level. As a result they are not defined here but in + * {@link TenantConfigurationKey} and injected using {@link EnvironmentAware}. * */ @Component @@ -20,17 +28,15 @@ import org.springframework.stereotype.Component; public class ControllerPollProperties { /** - * Recommended target polling time for DDI API. Final choice is up to the - * target. + * Maximum polling time that can be configured by a tenant in HH:MM:SS + * notation. */ - private String pollingTime; + private String maxPollingTime = "23:59:00"; /** - * Assumed time frame where the target is considered overdue when no DDI - * polling has been registered by the update server. + * Minimum polling time that can be configured by a tenant in HH:MM:SS + * notation. */ - private String pollingOverdueTime; - private String maxPollingTime = "23:59:00"; private String minPollingTime = "00:00:30"; public String getMaxPollingTime() { diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java index a4f92ccac..c83f24dc2 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.tenancy.configuration; import java.util.Arrays; import java.util.Optional; +import org.eclipse.hawkbit.ControllerPollProperties; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationBooleanValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationPollingDurationValidator; import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationStringValidator; @@ -20,7 +21,8 @@ import org.springframework.context.ApplicationContext; /** * An enum which defines the tenant specific configurations which can be - * configured for each tenant seperately. + * configured for each tenant separately. The non overridable properties are + * configured in {@link ControllerPollProperties} instead. * */ public enum TenantConfigurationKey { @@ -28,54 +30,40 @@ public enum TenantConfigurationKey { /** * boolean value {@code true} {@code false}. */ - AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", - "hawkbit.server.ddi.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(), - TenantConfigurationBooleanValidator.class), + AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", "hawkbit.server.ddi.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class), /** * */ - AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", - "hawkbit.server.ddi.security.authentication.header.authority", String.class, Boolean.FALSE.toString(), - TenantConfigurationStringValidator.class), + AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", "hawkbit.server.ddi.security.authentication.header.authority", String.class, Boolean.FALSE.toString(), TenantConfigurationStringValidator.class), /** * boolean value {@code true} {@code false}. */ - AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", - "hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.class, Boolean.FALSE.toString(), - TenantConfigurationBooleanValidator.class), + AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", "hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class), /** * boolean value {@code true} {@code false}. */ - AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", - "hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.class, Boolean.FALSE.toString(), - TenantConfigurationBooleanValidator.class), + AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", "hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class), /** * string value which holds the name of the security token key. */ - AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", - "hawkbit.server.ddi.security.authentication.gatewaytoken.name", String.class, null, - TenantConfigurationStringValidator.class), + AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", "hawkbit.server.ddi.security.authentication.gatewaytoken.name", String.class, null, TenantConfigurationStringValidator.class), /** * string value which holds the actual security-key of the gateway security * token. */ - AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", - "hawkbit.server.ddi.security.authentication.gatewaytoken.key", String.class, null, - TenantConfigurationStringValidator.class), + AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", "hawkbit.server.ddi.security.authentication.gatewaytoken.key", String.class, null, TenantConfigurationStringValidator.class), /** * string value which holds the polling time interval in the format HH:mm:ss */ - POLLING_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null, - TenantConfigurationPollingDurationValidator.class), + POLLING_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null, TenantConfigurationPollingDurationValidator.class), /** * string value which holds the polling time interval in the format HH:mm:ss */ - POLLING_OVERDUE_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null, - TenantConfigurationPollingDurationValidator.class); + POLLING_OVERDUE_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null, TenantConfigurationPollingDurationValidator.class); private final String keyName; private final String defaultKeyName; From f5539fd6073f4b54bc7c4e2a4935fb8e5f058024 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Mon, 14 Mar 2016 15:54:54 +0100 Subject: [PATCH 41/42] Add a controller management api to get the polling time Signed-off-by: SirWayne --- .../repository/ControllerManagement.java | 29 +++++++++++++++ .../TenantConfigurationManagement.java | 37 +++++++++++++++++-- .../hawkbit/controller/RootController.java | 14 ++----- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index b6fbb6010..7131bbe0a 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -33,7 +33,9 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.Target_; +import org.eclipse.hawkbit.repository.model.TenantConfiguration; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -86,6 +88,33 @@ public class ControllerManagement { @Autowired private HawkbitSecurityProperties securityProperties; + @Autowired + private TenantConfigurationRepository tenantConfigurationRepository; + + @Autowired + private TenantConfigurationManagement tenantConfigurationManagement; + + /** + * Retrieves all {@link SoftwareModule}s which are assigned to the given + * {@link DistributionSet}. + * + * @param distributionSet + * the distribution set which should be assigned to the returned + * {@link SoftwareModule}s + * @return a list of {@link SoftwareModule}s assigned to given + * {@code distributionSet} + */ + @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER) + public String findPollingTime() { + final TenantConfigurationKey configurationKey = TenantConfigurationKey.POLLING_TIME_INTERVAL; + final Class propertyType = String.class; + tenantConfigurationManagement.validateTenantConfigurationDataType(configurationKey, propertyType); + final TenantConfiguration tenantConfiguration = tenantConfigurationRepository + .findByKey(configurationKey.getKeyName()); + return tenantConfigurationManagement + .buildTenantConfigurationValueByKey(configurationKey, propertyType, tenantConfiguration).getValue(); + } + /** * Refreshes the time of the last time the controller has been connected to * the server. diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java index 3dbd6159e..f6b6afcfc 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/TenantConfigurationManagement.java @@ -85,16 +85,47 @@ public class TenantConfigurationManagement implements EnvironmentAware { + SpringEvalExpressions.IS_SYSTEM_CODE) public TenantConfigurationValue getConfigurationValue(final TenantConfigurationKey configurationKey, final Class propertyType) { + validateTenantConfigurationDataType(configurationKey, propertyType); + final TenantConfiguration tenantConfiguration = tenantConfigurationRepository + .findByKey(configurationKey.getKeyName()); + + return buildTenantConfigurationValueByKey(configurationKey, propertyType, tenantConfiguration); + } + + /** + * Validates the data type of the tenant configuration. If it is possible to + * cast to the given data type. + * + * @param configurationKey + * the key + * @param propertyType + * the class + */ + protected void validateTenantConfigurationDataType(final TenantConfigurationKey configurationKey, + final Class propertyType) { if (!configurationKey.getDataType().isAssignableFrom(propertyType)) { throw new TenantConfigurationValidatorException( String.format("Cannot parse the database value of type %s into the type %s.", configurationKey.getDataType(), propertyType)); } + } - final TenantConfiguration tenantConfiguration = tenantConfigurationRepository - .findByKey(configurationKey.getKeyName()); - + /** + * Build the tenant configuration by the given key + * + * @param configurationKey + * the key + * @param propertyType + * the property type + * @param tenantConfiguration + * the configuration + * @return if no default value is set and no database value available + * or returns the tenant configuration value + */ + protected TenantConfigurationValue buildTenantConfigurationValueByKey( + final TenantConfigurationKey configurationKey, final Class propertyType, + final TenantConfiguration tenantConfiguration) { if (tenantConfiguration != null) { return TenantConfigurationValue. builder().isGlobal(false).createdBy(tenantConfiguration.getCreatedBy()) .createdAt(tenantConfiguration.getCreatedAt()) diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java index 338ab689e..ff1e26f8b 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java @@ -30,7 +30,6 @@ import org.eclipse.hawkbit.controller.model.Result.FinalResult; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; -import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; @@ -43,7 +42,6 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; import org.eclipse.hawkbit.tenancy.TenantAware; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; import org.eclipse.hawkbit.util.IpUtil; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; @@ -93,9 +91,6 @@ public class RootController { @Autowired private TenantAware tenantAware; - @Autowired - private TenantConfigurationManagement tenantConfigurationManagement; - @Autowired private HawkbitSecurityProperties securityProperties; @@ -153,11 +148,10 @@ public class RootController { IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader())); } - final String pollingTime = tenantConfigurationManagement - .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue(); - - return new ResponseEntity<>(DataConversionHelper.fromTarget(target, - controllerManagement.findActionByTargetAndActive(target), pollingTime, tenantAware), HttpStatus.OK); + return new ResponseEntity<>( + DataConversionHelper.fromTarget(target, controllerManagement.findActionByTargetAndActive(target), + controllerManagement.findPollingTime(), tenantAware), + HttpStatus.OK); } /** From d4b18ce5e504e5f575e270c1cee80a6c6e5f0b1b Mon Sep 17 00:00:00 2001 From: Kai Zimmermann Date: Mon, 14 Mar 2016 16:08:41 +0100 Subject: [PATCH 42/42] Adapted the test to user different principals for repo prep and actual controller call --- .../controller/RootControllerTest.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java index 6a1ee73fc..a6e457f3a 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java @@ -74,7 +74,7 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB { @Test @Description("Ensures that target poll request does not change audit data on the entity.") @WithUser(principal = "knownPrincipal", authorities = { SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET, - SpPermission.CREATE_TARGET }) + SpPermission.CREATE_TARGET }, allSpPermissions = false) public void targetPollDoesNotModifyAuditData() throws Exception { // create target first with "knownPrincipal" user and audit data final String knownTargetControllerId = "target1"; @@ -135,16 +135,25 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB { } @Test - @Description("Ensures that tenant polling time, which is save in the db, exists.") - public void testModifyGloablPollingTime() throws Exception { - tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, - "00:02:00"); - - mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)) - .andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00"))); + @Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.") + @WithUser(principal = "knownpricipal", allSpPermissions = false) + public void pollWithModifiedGloablPollingTime() throws Exception { + securityRule.runAs( + WithSpringAuthorityRule.withUser("tenantadmin", SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION), + () -> { + tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, + "00:02:00"); + return null; + }); + securityRule.runAs( + WithSpringAuthorityRule.withUser("controller", SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), () -> { + mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)) + .andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00"))); + return null; + }); } @Test