Custom Tenant configuration. (#395)

* Tenant configuration configurable.
Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-12-23 07:19:46 +01:00
committed by GitHub
parent 4d35413f71
commit feb3369858
53 changed files with 730 additions and 447 deletions

View File

@@ -26,6 +26,7 @@ import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent;
import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
@@ -49,11 +50,10 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
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.TenantConfiguration;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -127,14 +127,8 @@ public class JpaControllerManagement implements ControllerManagement {
@Override
public String getPollingTime() {
final TenantConfigurationKey configurationKey = TenantConfigurationKey.POLLING_TIME_INTERVAL;
final Class<String> propertyType = String.class;
JpaTenantConfigurationManagement.validateTenantConfigurationDataType(configurationKey, propertyType);
final TenantConfiguration tenantConfiguration = tenantConfigurationRepository
.findByKey(configurationKey.getKeyName());
return systemSecurityContext.runAsSystem(() -> tenantConfigurationManagement
.buildTenantConfigurationValueByKey(configurationKey, propertyType, tenantConfiguration).getValue());
.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue());
}
@Override
@@ -203,10 +197,15 @@ public class JpaControllerManagement implements ControllerManagement {
final JpaTarget target = targetRepository.findOne(spec);
if (target == null) {
return targetManagement.createTarget(entityFactory.target().create().controllerId(controllerId)
.description("Plug and Play target: " + controllerId).name(controllerId)
final Target result = targetManagement.createTarget(entityFactory.target().create()
.controllerId(controllerId).description("Plug and Play target: " + controllerId).name(controllerId)
.status(TargetUpdateStatus.REGISTERED).lastTargetQuery(System.currentTimeMillis())
.address(Optional.ofNullable(address).map(URI::toString).orElse(null)));
afterCommit.afterCommit(
() -> eventPublisher.publishEvent(new TargetPollEvent(result, applicationContext.getId())));
return result;
}
return updateLastTargetQuery(target.getTargetInfo(), address).getTarget();
@@ -224,9 +223,6 @@ public class JpaControllerManagement implements ControllerManagement {
if (lastTargetQuery != null) {
mtargetInfo.setLastTargetQuery(lastTargetQuery);
}
if (address != null) {
mtargetInfo.setAddress(address.toString());
}
if (mtargetInfo.getUpdateStatus() == TargetUpdateStatus.UNKNOWN) {
mtargetInfo.setUpdateStatus(TargetUpdateStatus.REGISTERED);
@@ -234,6 +230,12 @@ public class JpaControllerManagement implements ControllerManagement {
.publishEvent(new TargetUpdatedEvent(mtargetInfo.getTarget(), applicationContext.getId())));
}
if (address != null) {
mtargetInfo.setAddress(address.toString());
afterCommit.afterCommit(() -> eventPublisher
.publishEvent(new TargetPollEvent(mtargetInfo.getTarget(), applicationContext.getId())));
}
return targetInfoRepository.save(mtargetInfo);
}

View File

@@ -14,16 +14,15 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantConfiguration;
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.TenantConfigurationProperties;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.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;
import org.springframework.context.ApplicationContext;
import org.springframework.context.EnvironmentAware;
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.Isolation;
import org.springframework.transaction.annotation.Transactional;
@@ -34,22 +33,26 @@ import org.springframework.validation.annotation.Validated;
*/
@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED)
@Validated
public class JpaTenantConfigurationManagement implements EnvironmentAware, TenantConfigurationManagement {
public class JpaTenantConfigurationManagement implements TenantConfigurationManagement {
@Autowired
private TenantConfigurationRepository tenantConfigurationRepository;
@Autowired
private TenantConfigurationProperties tenantConfigurationProperties;
@Autowired
private ApplicationContext applicationContext;
private static final ConfigurableConversionService conversionService = new DefaultConversionService();
private Environment environment;
@Override
@Cacheable(value = "tenantConfiguration", key = "#configurationKey.getKeyName()")
public <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(
final TenantConfigurationKey configurationKey, final Class<T> propertyType) {
@Cacheable(value = "tenantConfiguration", key = "#configurationKeyName")
public <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(final String configurationKeyName,
final Class<T> propertyType) {
final TenantConfigurationKey configurationKey = tenantConfigurationProperties.fromKeyName(configurationKeyName);
validateTenantConfigurationDataType(configurationKey, propertyType);
final TenantConfiguration tenantConfiguration = tenantConfigurationRepository
@@ -69,6 +72,7 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
*/
static <T> void validateTenantConfigurationDataType(final TenantConfigurationKey configurationKey,
final Class<T> propertyType) {
if (!configurationKey.getDataType().isAssignableFrom(propertyType)) {
throw new TenantConfigurationValidatorException(
String.format("Cannot parse the database value of type %s into the type %s.",
@@ -87,46 +91,44 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
.lastModifiedBy(tenantConfiguration.getLastModifiedBy())
.value(conversionService.convert(tenantConfiguration.getValue(), propertyType)).build();
} else if (configurationKey.getDefaultKeyName() != null) {
} else if (configurationKey.getDefaultValue() != null) {
return TenantConfigurationValue.<T> builder().global(true).createdBy(null).createdAt(null)
.lastModifiedAt(null).lastModifiedBy(null)
.value(getGlobalConfigurationValue(configurationKey, propertyType)).build();
.value(getGlobalConfigurationValue(configurationKey.getKeyName(), propertyType)).build();
}
return null;
}
@Override
public <T extends Serializable> TenantConfigurationValue<T> getConfigurationValue(
final TenantConfigurationKey configurationKey) {
return getConfigurationValue(configurationKey, configurationKey.getDataType());
final String configurationKeyName) {
final TenantConfigurationKey configurationKey = tenantConfigurationProperties.fromKeyName(configurationKeyName);
return getConfigurationValue(configurationKeyName, configurationKey.getDataType());
}
@Override
public <T> T getGlobalConfigurationValue(final TenantConfigurationKey configurationKey,
final Class<T> propertyType) {
public <T> T getGlobalConfigurationValue(final String configurationKeyName, final Class<T> 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 TenantConfigurationKey key = tenantConfigurationProperties.fromKeyName(configurationKeyName);
if (!key.getDataType().isAssignableFrom(propertyType)) {
throw new TenantConfigurationValidatorException(String.format(
"Cannot parse the database value of type %s into the type %s.", key.getDataType(), propertyType));
}
final T valueInProperties = environment.getProperty(configurationKey.getDefaultKeyName(), propertyType);
if (valueInProperties == null) {
return conversionService.convert(configurationKey.getDefaultValue(), propertyType);
}
return valueInProperties;
return conversionService.convert(key.getDefaultValue(), propertyType);
}
@Override
@CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()")
@CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName")
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public <T extends Serializable> TenantConfigurationValue<T> addOrUpdateConfiguration(
final TenantConfigurationKey configurationKey, final T value) {
final String configurationKeyName, final T value) {
final TenantConfigurationKey configurationKey = tenantConfigurationProperties.fromKeyName(configurationKeyName);
if (!configurationKey.getDataType().isAssignableFrom(value.getClass())) {
throw new TenantConfigurationValidatorException(String.format(
@@ -159,15 +161,10 @@ public class JpaTenantConfigurationManagement implements EnvironmentAware, Tenan
}
@Override
@CacheEvict(value = "tenantConfiguration", key = "#configurationKey.getKeyName()")
@CacheEvict(value = "tenantConfiguration", key = "#configurationKeyName")
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Modifying
public void deleteConfiguration(final TenantConfigurationKey configurationKey) {
tenantConfigurationRepository.deleteByKey(configurationKey.getKeyName());
}
@Override
public void setEnvironment(final Environment environment) {
this.environment = environment;
public void deleteConfiguration(final String configurationKeyName) {
tenantConfigurationRepository.deleteByKey(configurationKeyName);
}
}

View File

@@ -64,6 +64,7 @@ import org.eclipse.hawkbit.repository.rsql.RsqlValidationOracle;
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
@@ -94,7 +95,8 @@ import com.google.common.collect.Maps;
@EnableAspectJAutoProxy
@Configuration
@ComponentScan
@EnableConfigurationProperties({ RepositoryProperties.class, ControllerPollProperties.class, RolloutProperties.class })
@EnableConfigurationProperties({ RepositoryProperties.class, ControllerPollProperties.class, RolloutProperties.class,
TenantConfigurationProperties.class })
@EnableScheduling
@EntityScan("org.eclipse.hawkbit.repository.jpa.model")
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {

View File

@@ -48,7 +48,7 @@ import org.eclipse.hawkbit.repository.model.TargetInfo;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.helper.TenantConfigurationManagementHolder;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.eclipse.persistence.annotations.CascadeOnDelete;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;