hierarchical-validation-baseline #59
@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingItemsA
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemResource;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
|
||||
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -19,7 +20,6 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.validated;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||
|
||||
@RestController
|
||||
@ -62,7 +62,8 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
|
||||
final var entityToSave = mapper.map(body, HsBookingItemEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
final var saved = validated(bookingItemRepo.save(entityToSave));
|
||||
final HsBookingItemEntity entityToSave1 = bookingItemRepo.save(entityToSave);
|
||||
final var saved = HsBookingItemEntityValidatorRegistry.validated(entityToSave1);
|
||||
|
||||
final var uri =
|
||||
MvcUriComponentsBuilder.fromController(getClass())
|
||||
@ -118,7 +119,7 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
|
||||
new HsBookingItemEntityPatcher(current).apply(body);
|
||||
|
||||
final var saved = bookingItemRepo.save(validated(current));
|
||||
final var saved = bookingItemRepo.save(HsBookingItemEntityValidatorRegistry.validated(current));
|
||||
final var mapped = mapper.map(saved, HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
@ -1,64 +1,20 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
|
||||
import net.hostsharing.hsadminng.hs.validation.ValidatableProperty;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
|
||||
public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingItemEntity> {
|
||||
|
||||
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItemEntity>> validators = new HashMap<>();
|
||||
static {
|
||||
register(PRIVATE_CLOUD, new HsPrivateCloudBookingItemValidator());
|
||||
register(CLOUD_SERVER, new HsCloudServerBookingItemValidator());
|
||||
register(MANAGED_SERVER, new HsManagedServerBookingItemValidator());
|
||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceBookingItemValidator());
|
||||
}
|
||||
|
||||
private static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItemEntity> validator) {
|
||||
stream(validator.propertyValidators).forEach( entry -> {
|
||||
entry.verifyConsistency(Map.entry(type, validator));
|
||||
});
|
||||
validators.put(type, validator);
|
||||
}
|
||||
|
||||
public static HsEntityValidator<HsBookingItemEntity> forType(final Enum<HsBookingItemType> type) {
|
||||
if ( validators.containsKey(type)) {
|
||||
return validators.get(type);
|
||||
}
|
||||
throw new IllegalArgumentException("no validator found for type " + type);
|
||||
}
|
||||
|
||||
public static Set<Enum<HsBookingItemType>> types() {
|
||||
return validators.keySet();
|
||||
}
|
||||
|
||||
public static List<String> doValidate(final HsBookingItemEntity bookingItem) {
|
||||
return HsBookingItemEntityValidator.forType(bookingItem.getType()).validate(bookingItem);
|
||||
}
|
||||
|
||||
public static HsBookingItemEntity validated(final HsBookingItemEntity entityToSave) {
|
||||
MultiValidationException.throwInvalid(doValidate(entityToSave));
|
||||
return entityToSave;
|
||||
}
|
||||
|
||||
public HsBookingItemEntityValidator(final ValidatableProperty<?>... properties) {
|
||||
super(properties);
|
||||
}
|
||||
@ -72,7 +28,7 @@ public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingIte
|
||||
}
|
||||
|
||||
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
|
||||
return bookingItem != null ? HsBookingItemEntityValidator.doValidate(bookingItem) : emptyList();
|
||||
return bookingItem != null ? HsBookingItemEntityValidatorRegistry.doValidate(bookingItem) : emptyList();
|
||||
}
|
||||
|
||||
protected List<String> validateAgainstSubEntities(final HsBookingItemEntity bookingItem) {
|
||||
|
@ -0,0 +1,55 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
|
||||
public class HsBookingItemEntityValidatorRegistry {
|
||||
|
||||
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItemEntity>> validators = new HashMap<>();
|
||||
static {
|
||||
register(PRIVATE_CLOUD, new HsPrivateCloudBookingItemValidator());
|
||||
register(CLOUD_SERVER, new HsCloudServerBookingItemValidator());
|
||||
register(MANAGED_SERVER, new HsManagedServerBookingItemValidator());
|
||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceBookingItemValidator());
|
||||
}
|
||||
|
||||
private static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItemEntity> validator) {
|
||||
stream(validator.propertyValidators).forEach( entry -> {
|
||||
entry.verifyConsistency(Map.entry(type, validator));
|
||||
});
|
||||
validators.put(type, validator);
|
||||
}
|
||||
|
||||
public static HsEntityValidator<HsBookingItemEntity> forType(final Enum<HsBookingItemType> type) {
|
||||
if ( validators.containsKey(type)) {
|
||||
return validators.get(type);
|
||||
}
|
||||
throw new IllegalArgumentException("no validator found for type " + type);
|
||||
}
|
||||
|
||||
public static Set<Enum<HsBookingItemType>> types() {
|
||||
return validators.keySet();
|
||||
}
|
||||
|
||||
public static List<String> doValidate(final HsBookingItemEntity bookingItem) {
|
||||
return HsBookingItemEntityValidatorRegistry.forType(bookingItem.getType()).validate(bookingItem);
|
||||
}
|
||||
|
||||
public static HsBookingItemEntity validated(final HsBookingItemEntity entityToSave) {
|
||||
MultiValidationException.throwInvalid(doValidate(entityToSave));
|
||||
return entityToSave;
|
||||
}
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.validation.EnumerationProperty.enumerationProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerProperty.integerProperty;
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
@ -76,7 +76,7 @@ public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAs
|
||||
}
|
||||
|
||||
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
|
||||
return bookingItem != null ? HsBookingItemEntityValidator.doValidate(bookingItem) : emptyList();
|
||||
return bookingItem != null ? HsBookingItemEntityValidatorRegistry.doValidate(bookingItem) : emptyList();
|
||||
}
|
||||
|
||||
protected List<String> validateSubEntities(final HsHostingAssetEntity assetEntity) {
|
||||
|
@ -14,14 +14,12 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import jakarta.validation.ValidationException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static java.lang.String.join;
|
||||
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionTypeResource.*;
|
||||
|
||||
@RestController
|
||||
|
@ -15,14 +15,12 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static java.lang.String.join;
|
||||
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.CANCELLATION;
|
||||
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.SUBSCRIPTION;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.hs.validation;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -52,9 +52,9 @@ public abstract class HsEntityValidator<E> {
|
||||
}
|
||||
|
||||
protected List<String> validateParentEntities(final HsBookingItemEntity bookingItem) {
|
||||
return bookingItem.getParentItem() != null
|
||||
? HsBookingItemEntityValidator.doValidate(bookingItem.getParentItem())
|
||||
: emptyList();
|
||||
return bookingItem.getParentItem() != null ?
|
||||
HsBookingItemEntityValidatorRegistry.doValidate(bookingItem.getParentItem()) :
|
||||
emptyList();
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
|
@ -11,7 +11,6 @@ import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVAT
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.validated;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
@ -34,7 +33,7 @@ class HsBookingItemEntityValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = catchThrowable( ()-> validated(cloudServerBookingItemEntity) );
|
||||
final var result = catchThrowable( ()-> HsBookingItemEntityValidatorRegistry.validated(cloudServerBookingItemEntity));
|
||||
|
||||
// then
|
||||
assertThat(result).isInstanceOf(ValidationException.class)
|
||||
@ -48,7 +47,7 @@ class HsBookingItemEntityValidatorUnitTest {
|
||||
@Test
|
||||
void listsTypes() {
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.types();
|
||||
final var result = HsBookingItemEntityValidatorRegistry.types();
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER, MANAGED_WEBSPACE);
|
||||
|
@ -13,7 +13,6 @@ import static java.util.Map.ofEntries;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsCloudServerBookingItemValidatorUnitTest {
|
||||
@ -43,7 +42,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(cloudServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(cloudServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("D-12345:Test-Project:Test-Server.resources.SLA-EMail is not expected but is set to 'true'");
|
||||
@ -52,7 +51,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = forType(CLOUD_SERVER);
|
||||
final var validator = HsBookingItemEntityValidatorRegistry.forType(CLOUD_SERVER);
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
@ -106,7 +105,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(subCloudServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(subCloudServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
|
@ -21,7 +21,6 @@ import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedServerBookingItemValidatorUnitTest {
|
||||
@ -51,7 +50,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(mangedServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("D-12345:Test-Project:null.resources.SLA-EMail is expected to be false because SLA-Platform=BASIC but is true");
|
||||
@ -60,7 +59,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = forType(MANAGED_SERVER);
|
||||
final var validator = HsBookingItemEntityValidatorRegistry.forType(MANAGED_SERVER);
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
@ -117,7 +116,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(subManagedServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(subManagedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@ -163,7 +162,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(managedWebspaceBookingItem);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(managedWebspaceBookingItem);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
|
@ -37,7 +37,7 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(mangedServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@ -51,7 +51,7 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = HsBookingItemEntityValidator.forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsBookingItemEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
|
@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
import static java.util.List.of;
|
||||
import static java.util.Map.entry;
|
||||
import static java.util.Map.ofEntries;
|
||||
@ -48,7 +47,7 @@ class HsPrivateCloudBookingItemValidatorTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(privateCloudBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).isEmpty();
|
||||
@ -88,7 +87,7 @@ class HsPrivateCloudBookingItemValidatorTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidator.doValidate(privateCloudBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
|
Loading…
Reference in New Issue
Block a user