From ec79e9bd195cde79313e4ec3b84d82c5613d6374 Mon Sep 17 00:00:00 2001 From: Fabian Nonnenmacher Date: Thu, 28 Jan 2016 18:44:31 +0100 Subject: [PATCH] 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);