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 <fabian.nonnenmacher@bosch-si.com>
This commit is contained in:
Fabian Nonnenmacher
2016-01-27 17:00:39 +01:00
committed by Nonnenmacher Fabian
parent b56477191a
commit 6cef6aed1a
29 changed files with 466 additions and 373 deletions

View File

@@ -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();
}
}

View File

@@ -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<String> 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 <T>
*
* @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 <T> TenantConfigurationValue<T> getConfigurationValue(final TenantConfigurationKey configurationKey,
final Class<T> propertyType) {
final TenantConfiguration tenantConfiguration = tenantConfigurationRepository
.findByKey(configurationKey.getKeyName());
if (tenantConfiguration != null) {
return TenantConfigurationValue.<T> 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.<T> 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<TenantConfiguration> 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);
// }
}

View File

@@ -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 <T>
*
* @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 <T> TenantConfigurationValue<T> getConfigurationValue(final TenantConfigurationKey configurationKey,
final Class<T> propertyType) {
final TenantConfiguration tenantConfiguration = tenantConfigurationRepository
.findByKey(configurationKey.getKeyName());
if (tenantConfiguration != null) {
return TenantConfigurationValue.<T> 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.<T> 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<TenantConfiguration> getTenantConfigurations() {
return tenantConfigurationRepository.findAll();
}
@Override
public void setEnvironment(final Environment environment) {
this.environment = environment;
}
}

View File

@@ -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<Long>, 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<Long>, 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());

View File

@@ -41,7 +41,7 @@ public class TenantConfigurationValue<T> {
*
* @return the last modified at
*/
public long getLastModifiedAt() {
public Long getLastModifiedAt() {
return lastModifiedAt;
}
@@ -59,7 +59,7 @@ public class TenantConfigurationValue<T> {
*
* @return the created at
*/
public long getCreatedAt() {
public Long getCreatedAt() {
return createdAt;
}