fix potential class loading deadlock in HsHostingAssetEntityValidator
This commit is contained in:
parent
0b307ffdb7
commit
5f2117b5b5
@ -1,5 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidatorRegistry;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
@ -20,8 +21,6 @@ import java.util.List;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.validated;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class HsHostingAssetController implements HsHostingAssetsApi {
|
public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||||
|
|
||||||
@ -62,7 +61,8 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
|||||||
|
|
||||||
final var entityToSave = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
final var entityToSave = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||||
|
|
||||||
final var saved = validated(assetRepo.save(entityToSave));
|
final HsHostingAssetEntity persistentEntity = assetRepo.save(entityToSave);
|
||||||
|
final var saved = HsHostingAssetEntityValidatorRegistry.validated(persistentEntity);
|
||||||
|
|
||||||
final var uri =
|
final var uri =
|
||||||
MvcUriComponentsBuilder.fromController(getClass())
|
MvcUriComponentsBuilder.fromController(getClass())
|
||||||
@ -117,7 +117,8 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
|||||||
|
|
||||||
new HsHostingAssetEntityPatcher(current).apply(body);
|
new HsHostingAssetEntityPatcher(current).apply(body);
|
||||||
|
|
||||||
final var saved = validated(assetRepo.save(current));
|
final HsHostingAssetEntity persistentEntity = assetRepo.save(current);
|
||||||
|
final var saved = HsHostingAssetEntityValidatorRegistry.validated(persistentEntity);
|
||||||
final var mapped = mapper.map(saved, HsHostingAssetResource.class);
|
final var mapped = mapper.map(saved, HsHostingAssetResource.class);
|
||||||
return ResponseEntity.ok(mapped);
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator;
|
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidatorRegistry;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetPropsApi;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetPropsApi;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@ -15,7 +15,7 @@ public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<List<String>> listAssetTypes() {
|
public ResponseEntity<List<String>> listAssetTypes() {
|
||||||
final var resource = HsHostingAssetEntityValidator.types().stream()
|
final var resource = HsHostingAssetEntityValidatorRegistry.types().stream()
|
||||||
.map(Enum::name)
|
.map(Enum::name)
|
||||||
.toList();
|
.toList();
|
||||||
return ResponseEntity.ok(resource);
|
return ResponseEntity.ok(resource);
|
||||||
@ -25,7 +25,8 @@ public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
|||||||
public ResponseEntity<List<Object>> listAssetTypeProps(
|
public ResponseEntity<List<Object>> listAssetTypeProps(
|
||||||
final HsHostingAssetTypeResource assetType) {
|
final HsHostingAssetTypeResource assetType) {
|
||||||
|
|
||||||
final var propValidators = HsHostingAssetEntityValidator.forType(HsHostingAssetType.of(assetType));
|
final Enum<HsHostingAssetType> type = HsHostingAssetType.of(assetType);
|
||||||
|
final var propValidators = HsHostingAssetEntityValidatorRegistry.forType(type);
|
||||||
final List<Map<String, Object>> resource = propValidators.properties();
|
final List<Map<String, Object>> resource = propValidators.properties();
|
||||||
return ResponseEntity.ok(toListOfObjects(resource));
|
return ResponseEntity.ok(toListOfObjects(resource));
|
||||||
}
|
}
|
||||||
|
@ -3,59 +3,18 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
|
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
|
||||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||||
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
|
|
||||||
import net.hostsharing.hsadminng.hs.validation.ValidatableProperty;
|
import net.hostsharing.hsadminng.hs.validation.ValidatableProperty;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static java.util.Arrays.stream;
|
import static java.util.Arrays.stream;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Optional.ofNullable;
|
import static java.util.Optional.ofNullable;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.*;
|
|
||||||
|
|
||||||
public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity> {
|
public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity> {
|
||||||
|
|
||||||
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity>> validators = new HashMap<>();
|
|
||||||
static {
|
|
||||||
register(CLOUD_SERVER, new HsHostingAssetEntityValidator());
|
|
||||||
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
|
|
||||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
|
||||||
register(UNIX_USER, new HsHostingAssetEntityValidator());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity> validator) {
|
|
||||||
stream(validator.propertyValidators).forEach( entry -> {
|
|
||||||
entry.verifyConsistency(Map.entry(type, validator));
|
|
||||||
});
|
|
||||||
validators.put(type, validator);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HsEntityValidator<HsHostingAssetEntity> forType(final Enum<HsHostingAssetType> type) {
|
|
||||||
if ( validators.containsKey(type)) {
|
|
||||||
return validators.get(type);
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("no validator found for type " + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Set<Enum<HsHostingAssetType>> types() {
|
|
||||||
return validators.keySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> doValidate(final HsHostingAssetEntity hostingAsset) {
|
|
||||||
return HsHostingAssetEntityValidator.forType(hostingAsset.getType()).validate(hostingAsset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HsHostingAssetEntity validated(final HsHostingAssetEntity entityToSave) {
|
|
||||||
MultiValidationException.throwInvalid(doValidate(entityToSave));
|
|
||||||
return entityToSave;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HsHostingAssetEntityValidator(final ValidatableProperty<?>... properties) {
|
public HsHostingAssetEntityValidator(final ValidatableProperty<?>... properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
@ -72,7 +31,9 @@ public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAs
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> optionallyValidate(final HsHostingAssetEntity assetEntity) {
|
private static List<String> optionallyValidate(final HsHostingAssetEntity assetEntity) {
|
||||||
return assetEntity != null ? forType(assetEntity.getType()).validate(assetEntity) : emptyList();
|
return assetEntity != null ?
|
||||||
|
HsHostingAssetEntityValidatorRegistry.forType(assetEntity.getType()).validate(assetEntity) :
|
||||||
|
emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
|
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||||
|
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||||
|
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||||
|
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||||
|
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static java.util.Arrays.stream;
|
||||||
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.*;
|
||||||
|
|
||||||
|
public class HsHostingAssetEntityValidatorRegistry {
|
||||||
|
|
||||||
|
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity>> validators = new HashMap<>();
|
||||||
|
static {
|
||||||
|
register(CLOUD_SERVER, new HsHostingAssetEntityValidator());
|
||||||
|
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
|
||||||
|
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
||||||
|
register(UNIX_USER, new HsHostingAssetEntityValidator());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity> validator) {
|
||||||
|
stream(validator.propertyValidators).forEach( entry -> {
|
||||||
|
entry.verifyConsistency(Map.entry(type, validator));
|
||||||
|
});
|
||||||
|
validators.put(type, validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HsEntityValidator<HsHostingAssetEntity> forType(final Enum<HsHostingAssetType> type) {
|
||||||
|
if ( validators.containsKey(type)) {
|
||||||
|
return validators.get(type);
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("no validator found for type " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Enum<HsHostingAssetType>> types() {
|
||||||
|
return validators.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> doValidate(final HsHostingAssetEntity hostingAsset) {
|
||||||
|
return HsHostingAssetEntityValidatorRegistry.forType(hostingAsset.getType()).validate(hostingAsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HsHostingAssetEntity validated(final HsHostingAssetEntity entityToSave) {
|
||||||
|
MultiValidationException.throwInvalid(doValidate(entityToSave));
|
||||||
|
return entityToSave;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -7,7 +7,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.forType;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
class HsCloudServerHostingAssetValidatorUnitTest {
|
class HsCloudServerHostingAssetValidatorUnitTest {
|
||||||
@ -22,7 +21,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
|||||||
entry("RAM", 2000)
|
entry("RAM", 2000)
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
final var validator = forType(cloudServerHostingAssetEntity.getType());
|
final var validator = HsHostingAssetEntityValidatorRegistry.forType(cloudServerHostingAssetEntity.getType());
|
||||||
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -35,7 +34,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void containsAllValidations() {
|
void containsAllValidations() {
|
||||||
// when
|
// when
|
||||||
final var validator = forType(CLOUD_SERVER);
|
final var validator = HsHostingAssetEntityValidatorRegistry.forType(CLOUD_SERVER);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(validator.properties()).map(Map::toString).isEmpty();
|
assertThat(validator.properties()).map(Map::toString).isEmpty();
|
||||||
|
@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.validated;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||||
|
|
||||||
@ -21,7 +20,7 @@ class HsHostingAssetEntityValidatorUnitTest {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = catchThrowable( ()-> validated(managedServerHostingAssetEntity) );
|
final var result = catchThrowable( ()-> HsHostingAssetEntityValidatorRegistry.validated(managedServerHostingAssetEntity));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).isInstanceOf(ValidationException.class)
|
assertThat(result).isInstanceOf(ValidationException.class)
|
||||||
|
@ -7,7 +7,6 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.forType;
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
class HsManagedServerHostingAssetValidatorUnitTest {
|
class HsManagedServerHostingAssetValidatorUnitTest {
|
||||||
@ -24,7 +23,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
|||||||
entry("monit_max_ram_usage", 101)
|
entry("monit_max_ram_usage", 101)
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
final var validator = forType(mangedWebspaceHostingAssetEntity.getType());
|
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedWebspaceHostingAssetEntity.getType());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||||
|
@ -42,7 +42,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void validatesIdentifier() {
|
void validatesIdentifier() {
|
||||||
// given
|
// given
|
||||||
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE);
|
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
.type(MANAGED_WEBSPACE)
|
.type(MANAGED_WEBSPACE)
|
||||||
.parentAsset(mangedServerAssetEntity)
|
.parentAsset(mangedServerAssetEntity)
|
||||||
@ -59,7 +59,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void validatesUnknownProperties() {
|
void validatesUnknownProperties() {
|
||||||
// given
|
// given
|
||||||
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE);
|
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
.type(MANAGED_WEBSPACE)
|
.type(MANAGED_WEBSPACE)
|
||||||
.parentAsset(mangedServerAssetEntity)
|
.parentAsset(mangedServerAssetEntity)
|
||||||
@ -79,7 +79,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void validatesValidEntity() {
|
void validatesValidEntity() {
|
||||||
// given
|
// given
|
||||||
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE);
|
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
.type(MANAGED_WEBSPACE)
|
.type(MANAGED_WEBSPACE)
|
||||||
.parentAsset(mangedServerAssetEntity)
|
.parentAsset(mangedServerAssetEntity)
|
||||||
|
Loading…
Reference in New Issue
Block a user