REST API extend System Configuration to support Default DistributionS… (#1457)

* REST API extend System Configuration to support Default DistributionSet Type

* Remove leftover comment

* After review - changing the Default DistributionSetType  type to long

* After review - Remove CustomMatcher for Numbers equals, rename test methods to more descriptive naming

* Simplify
This commit is contained in:
Vasil Ilchev
2023-10-24 11:02:36 +03:00
committed by GitHub
parent 7e8b3ad97f
commit 0e631e0f3b
3 changed files with 272 additions and 59 deletions

View File

@@ -11,49 +11,39 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
/**
* A mapper which maps repository model to RESTful model representation and
* back.
*/
public final class MgmtTenantManagementMapper {
public static String DEFAULT_DISTRIBUTION_SET_TYPE_KEY = "default.ds.type";
private MgmtTenantManagementMapper() {
// Utility class
}
static Map<String, MgmtSystemTenantConfigurationValue> toResponse(
final TenantConfigurationManagement tenantConfigurationManagement,
final TenantConfigurationProperties tenantConfigurationProperties) {
return tenantConfigurationProperties.getConfigurationKeys().stream()
.collect(Collectors.toMap(TenantConfigurationKey::getKeyName, key -> toResponse(key.getKeyName(),
tenantConfigurationManagement.getConfigurationValue(key.getKeyName()))));
}
static MgmtSystemTenantConfigurationValue toResponse(final String key,
final TenantConfigurationValue<?> repoConfValue) {
public static MgmtSystemTenantConfigurationValue toResponseTenantConfigurationValue(String key, TenantConfigurationValue<?> repoConfValue) {
final MgmtSystemTenantConfigurationValue restConfValue = new MgmtSystemTenantConfigurationValue();
restConfValue.setValue(repoConfValue.getValue());
restConfValue.setGlobal(repoConfValue.isGlobal());
restConfValue.setCreatedAt(repoConfValue.getCreatedAt());
restConfValue.setCreatedBy(repoConfValue.getCreatedBy());
restConfValue.setLastModifiedAt(repoConfValue.getLastModifiedAt());
restConfValue.setLastModifiedBy(repoConfValue.getLastModifiedBy());
restConfValue.add(linkTo(methodOn(MgmtTenantManagementResource.class).getTenantConfigurationValue(key))
.withSelfRel().expand());
return restConfValue;
}
public static MgmtSystemTenantConfigurationValue toResponseDefaultDsType(Long defaultDistributionSetType) {
final MgmtSystemTenantConfigurationValue restConfValue = new MgmtSystemTenantConfigurationValue();
restConfValue.setValue(defaultDistributionSetType);
restConfValue.setGlobal(Boolean.FALSE);
restConfValue.add(linkTo(methodOn(MgmtTenantManagementResource.class).getTenantConfigurationValue(DEFAULT_DISTRIBUTION_SET_TYPE_KEY))
.withSelfRel().expand());
return restConfValue;
}
}

View File

@@ -13,13 +13,16 @@ import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue;
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTenantManagementRestApi;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties;
import org.eclipse.hawkbit.tenancy.configuration.validator.TenantConfigurationValidatorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
@@ -38,45 +41,77 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
private final TenantConfigurationManagement tenantConfigurationManagement;
private final TenantConfigurationProperties tenantConfigurationProperties;
private final SystemManagement systemManagement;
MgmtTenantManagementResource(final TenantConfigurationManagement tenantConfigurationManagement,
final TenantConfigurationProperties tenantConfigurationProperties) {
final TenantConfigurationProperties tenantConfigurationProperties,
final SystemManagement systemManagement) {
this.tenantConfigurationManagement = tenantConfigurationManagement;
this.tenantConfigurationProperties = tenantConfigurationProperties;
this.systemManagement = systemManagement;
}
@Override
public ResponseEntity<Map<String, MgmtSystemTenantConfigurationValue>> getTenantConfiguration() {
return ResponseEntity.ok(
MgmtTenantManagementMapper.toResponse(tenantConfigurationManagement, tenantConfigurationProperties));
//Load and Construct default Tenant Configuration
Map<String, MgmtSystemTenantConfigurationValue> tenantConfigurationValueMap = tenantConfigurationProperties.getConfigurationKeys().stream().collect(
Collectors.toMap(TenantConfigurationProperties.TenantConfigurationKey::getKeyName,
key -> loadTenantConfigurationValueBy(key.getKeyName())));
//Load and Add Default DistributionSetType
MgmtSystemTenantConfigurationValue defaultDsTypeId = loadTenantConfigurationValueBy(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY);
tenantConfigurationValueMap.put(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY, defaultDsTypeId);
//return combined TenantConfiguration and TenantMetadata
LOG.debug("getTenantConfiguration, return status {}", HttpStatus.OK);
return ResponseEntity.ok(tenantConfigurationValueMap);
}
@Override
public ResponseEntity<MgmtSystemTenantConfigurationValue> getTenantConfigurationValue(
@PathVariable("keyName") final String keyName) {
return ResponseEntity.ok(loadTenantConfigurationValueBy(keyName));
}
private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(String keyName) {
//Check if requested key is TenantConfiguration or TenantMetadata, load it and return it as rest response
MgmtSystemTenantConfigurationValue response;
if (isDefaultDistributionSetTypeKey(keyName)) {
response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId());
} else {
response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, tenantConfigurationManagement.getConfigurationValue(keyName));
}
return response;
}
@Override
public ResponseEntity<Void> deleteTenantConfigurationValue(@PathVariable("keyName") final String keyName) {
//Default DistributionSet Type cannot be deleted as is part of TenantMetadata
if (isDefaultDistributionSetTypeKey(keyName)) {
return ResponseEntity.badRequest().build();
}
tenantConfigurationManagement.deleteConfiguration(keyName);
LOG.debug("{} config value deleted, return status {}", keyName, HttpStatus.OK);
return ResponseEntity.ok().build();
}
@Override
public ResponseEntity<MgmtSystemTenantConfigurationValue> getTenantConfigurationValue(
@PathVariable("keyName") final String keyName) {
LOG.debug("{} config value getted, return status {}", keyName, HttpStatus.OK);
return ResponseEntity.ok(MgmtTenantManagementMapper.toResponse(keyName,
tenantConfigurationManagement.getConfigurationValue(keyName)));
}
@Override
public ResponseEntity<MgmtSystemTenantConfigurationValue> updateTenantConfigurationValue(
@PathVariable("keyName") final String keyName,
@RequestBody final MgmtSystemTenantConfigurationValueRequest configurationValueRest) {
final TenantConfigurationValue<? extends Serializable> updatedValue = tenantConfigurationManagement
Serializable configurationValue = configurationValueRest.getValue();
final MgmtSystemTenantConfigurationValue responseUpdatedValue;
if (isDefaultDistributionSetTypeKey(keyName)) {
responseUpdatedValue = updateDefaultDsType(configurationValue);
} else {
final TenantConfigurationValue<? extends Serializable> updatedTenantConfigurationValue = tenantConfigurationManagement
.addOrUpdateConfiguration(keyName, configurationValueRest.getValue());
return ResponseEntity.ok(MgmtTenantManagementMapper.toResponse(keyName, updatedValue));
responseUpdatedValue = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, updatedTenantConfigurationValue);
}
return ResponseEntity.ok(responseUpdatedValue);
}
@Override
@@ -90,11 +125,50 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
return ResponseEntity.badRequest().build();
}
Map<String, TenantConfigurationValue<Serializable>> tenantConfigurationValues = tenantConfigurationManagement
.addOrUpdateConfiguration(configurationValueMap);
//Try update TenantMetadata first
Serializable defaultDsTypeValueUpdate = configurationValueMap.remove(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY);
Long oldDefaultDsType = null;
MgmtSystemTenantConfigurationValue updatedDefaultDsType = null;
if (defaultDsTypeValueUpdate != null) {
oldDefaultDsType = systemManagement.getTenantMetadata().getDefaultDsType().getId();
updatedDefaultDsType = updateDefaultDsType(defaultDsTypeValueUpdate);
}
//try update TenantConfiguration, in case of Error -> rollback TenantMetadata
Map<String, TenantConfigurationValue<Serializable>> tenantConfigurationValues;
try {
tenantConfigurationValues = tenantConfigurationManagement.addOrUpdateConfiguration(configurationValueMap);
} catch (Exception ex) {
//if DefaultDsType was updated, rollback it in case of TenantConfiguration update.
if (updatedDefaultDsType != null) {
systemManagement.updateTenantMetadata(oldDefaultDsType);
}
throw ex;
}
return ResponseEntity.ok(tenantConfigurationValues.entrySet().stream().map(entry ->
MgmtTenantManagementMapper.toResponse(entry.getKey(), entry.getValue())).toList());
List<MgmtSystemTenantConfigurationValue> tenantConfigurationListUpdated = new java.util.ArrayList<>(tenantConfigurationValues.entrySet().stream()
.map(entry -> MgmtTenantManagementMapper.toResponseTenantConfigurationValue(entry.getKey(), entry.getValue())).toList());
if (updatedDefaultDsType != null) {
tenantConfigurationListUpdated.add(updatedDefaultDsType);
}
return ResponseEntity.ok(tenantConfigurationListUpdated);
}
private MgmtSystemTenantConfigurationValue updateDefaultDsType(Serializable defaultDsType) {
long updateDefaultDsType;
try {
updateDefaultDsType = ((Number) defaultDsType).longValue();
} catch (ClassCastException cce) {
throw new TenantConfigurationValidatorException(String.format(
"Default DistributionSetType Value Type is incorrect. Expected Long, received %s", defaultDsType.getClass().getName()));
}
systemManagement.updateTenantMetadata(updateDefaultDsType);
return MgmtTenantManagementMapper.toResponseDefaultDsType(updateDefaultDsType);
}
private static boolean isDefaultDistributionSetTypeKey(String keyName) {
return MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY.equals(keyName);
}
}