hierarchical-validation-baseline #59
@ -19,6 +19,7 @@ import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
@ -27,12 +28,14 @@ import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
import jakarta.persistence.Version;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -105,6 +108,10 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject, Validatab
|
||||
@Column(columnDefinition = "resources")
|
||||
private Map<String, Object> resources = new HashMap<>();
|
||||
|
||||
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true)
|
||||
@JoinColumn(name="parentitemuuid", referencedColumnName="uuid")
|
||||
private List<HsBookingItemEntity> subBookingItems;
|
||||
|
||||
@Transient
|
||||
private PatchableMapWrapper<Object> resourcesWrapper;
|
||||
|
||||
|
@ -7,6 +7,7 @@ import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@ -14,12 +15,14 @@ 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;
|
||||
|
||||
@UtilityClass
|
||||
public class HsBookingItemEntityValidators {
|
||||
|
||||
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItemEntity, HsBookingItemType>> validators = new HashMap<>();
|
||||
static {
|
||||
register(PRIVATE_CLOUD, new HsPrivateCloudBookingItemValidator());
|
||||
register(CLOUD_SERVER, new HsCloudServerBookingItemValidator());
|
||||
register(MANAGED_SERVER, new HsManagedServerBookingItemValidator());
|
||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceBookingItemValidator());
|
||||
@ -41,10 +44,14 @@ public class HsBookingItemEntityValidators {
|
||||
}
|
||||
|
||||
public static HsBookingItemEntity valid(final HsBookingItemEntity entityToSave) {
|
||||
final var violations = HsBookingItemEntityValidators.forType(entityToSave.getType()).validate(entityToSave);
|
||||
final var violations = validate(entityToSave);
|
||||
if (!violations.isEmpty()) {
|
||||
throw new ValidationException(violations.toString());
|
||||
}
|
||||
return entityToSave;
|
||||
}
|
||||
|
||||
public static List<String> validate(final HsBookingItemEntity bookingItem) {
|
||||
return HsBookingItemEntityValidators.forType(bookingItem.getType()).validate(bookingItem);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.validation.EnumerationPropertyValidator.enumerationProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
||||
|
||||
@ -19,4 +21,10 @@ class HsCloudServerBookingItemValidator extends HsEntityValidator<HsBookingItemE
|
||||
enumerationProperty("SLA-Infrastructure").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> validate(final HsBookingItemEntity cloudServerBookingItem) {
|
||||
final var selfValidation = super.validate(cloudServerBookingItem);
|
||||
return !selfValidation.isEmpty() ? selfValidation : validateParentEntities(cloudServerBookingItem);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.validation.BooleanPropertyValidator.booleanProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.EnumerationPropertyValidator.enumerationProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
||||
@ -25,4 +27,11 @@ class HsManagedServerBookingItemValidator extends HsEntityValidator<HsBookingIte
|
||||
booleanProperty("SLA-Web").falseIf("SLA-Platform", "BASIC").optional()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> validate(final HsBookingItemEntity managedServerBookingItem) {
|
||||
final var selfValidation = super.validate(managedServerBookingItem);
|
||||
return !selfValidation.isEmpty() ? selfValidation : validateParentEntities(managedServerBookingItem);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
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 java.util.List;
|
||||
|
||||
import static java.util.EnumSet.of;
|
||||
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.validation.EnumerationPropertyValidator.enumerationProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
||||
|
||||
class HsPrivateCloudBookingItemValidator extends HsEntityValidator<HsBookingItemEntity, HsBookingItemType> {
|
||||
|
||||
HsPrivateCloudBookingItemValidator() {
|
||||
super(
|
||||
integerProperty("CPUs").min(4).max(128).required(),
|
||||
integerProperty("RAM").unit("GB").min(4).max(512).required(),
|
||||
integerProperty("SSD").unit("GB").min(100).max(4000).step(25).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(16000).step(25).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(1000).max(40000).step(250).required(),
|
||||
enumerationProperty("SLA-Infrastructure").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> validate(final HsBookingItemEntity privateCloudBookingItem) {
|
||||
final var selfValidation = super.validate(privateCloudBookingItem);
|
||||
return !selfValidation.isEmpty() ? selfValidation : validateSubEntities(privateCloudBookingItem);
|
||||
}
|
||||
|
||||
private List<String> validateSubEntities(final HsBookingItemEntity privateCloudBookingItem) {
|
||||
return validateSubEntities(privateCloudBookingItem, of(CLOUD_SERVER, MANAGED_SERVER));
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidators.valid;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.valid;
|
||||
|
||||
@RestController
|
||||
public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidators;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator;
|
||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetPropsApi;
|
||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -15,7 +15,7 @@ public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
||||
|
||||
@Override
|
||||
public ResponseEntity<List<String>> listAssetTypes() {
|
||||
final var resource = HsHostingAssetEntityValidators.types().stream()
|
||||
final var resource = HsHostingAssetEntityValidator.types().stream()
|
||||
.map(Enum::name)
|
||||
.toList();
|
||||
return ResponseEntity.ok(resource);
|
||||
@ -25,7 +25,7 @@ public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
|
||||
public ResponseEntity<List<Object>> listAssetTypeProps(
|
||||
final HsHostingAssetTypeResource assetType) {
|
||||
|
||||
final var propValidators = HsHostingAssetEntityValidators.forType(HsHostingAssetType.of(assetType));
|
||||
final var propValidators = HsHostingAssetEntityValidator.forType(HsHostingAssetType.of(assetType));
|
||||
final List<Map<String, Object>> resource = propValidators.properties();
|
||||
return ResponseEntity.ok(toListOfObjects(resource));
|
||||
}
|
||||
|
@ -1,22 +1,25 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidators;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
import org.apache.commons.collections4.ListUtils;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||
|
||||
@UtilityClass
|
||||
public class HsHostingAssetEntityValidators {
|
||||
public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType>> validators = new HashMap<>();
|
||||
static {
|
||||
@ -40,12 +43,30 @@ public class HsHostingAssetEntityValidators {
|
||||
return validators.keySet();
|
||||
}
|
||||
|
||||
|
||||
public static HsHostingAssetEntity valid(final HsHostingAssetEntity entityToSave) {
|
||||
final var violations = HsHostingAssetEntityValidators.forType(entityToSave.getType()).validate(entityToSave);
|
||||
final var violations = HsHostingAssetEntityValidator.forType(entityToSave.getType()).validate(entityToSave);
|
||||
if (!violations.isEmpty()) {
|
||||
throw new ValidationException(violations.toString());
|
||||
}
|
||||
return entityToSave;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> validate(final HsHostingAssetEntity assetEntity) {
|
||||
final var selfValidation = super.validate(assetEntity);
|
||||
return selfValidation.isEmpty()
|
||||
// higher levels are only validated with valid sub-entity
|
||||
? ListUtils.union(
|
||||
optionallyValidate(assetEntity.getParentAsset()),
|
||||
optionallyValidate(assetEntity.getBookingItem()))
|
||||
: selfValidation;
|
||||
}
|
||||
|
||||
private static List<String> optionallyValidate(final HsHostingAssetEntity assetEntity) {
|
||||
return assetEntity != null ? forType(assetEntity.getType()).validate(assetEntity) : emptyList();
|
||||
}
|
||||
|
||||
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
|
||||
return bookingItem != null ? HsBookingItemEntityValidators.validate(bookingItem) : emptyList();
|
||||
}
|
||||
}
|
@ -3,13 +3,20 @@ package net.hostsharing.hsadminng.hs.validation;
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
||||
public class HsEntityValidator<E extends Validatable<E, T>, T extends Enum<T>> {
|
||||
|
||||
@ -32,7 +39,7 @@ public class HsEntityValidator<E extends Validatable<E, T>, T extends Enum<T>> {
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<Map<String, Object>> properties() {
|
||||
public final List<Map<String, Object>> properties() {
|
||||
final var mapper = new ObjectMapper();
|
||||
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
|
||||
return Arrays.stream(propertyValidators)
|
||||
@ -46,4 +53,40 @@ public class HsEntityValidator<E extends Validatable<E, T>, T extends Enum<T>> {
|
||||
return (Map<String, Object>) map;
|
||||
}
|
||||
|
||||
protected List<String> validateSubEntities(
|
||||
final HsBookingItemEntity assetEntity,
|
||||
final EnumSet<HsBookingItemType> subItemTypes) {
|
||||
return properties().stream()
|
||||
.map(prop -> validateMaxTotalValue(assetEntity, subItemTypes, prop))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
|
||||
protected String validateMaxTotalValue(
|
||||
final HsBookingItemEntity assetEntity,
|
||||
final EnumSet<HsBookingItemType> subTypes,
|
||||
final Map<String, Object> propDef) {
|
||||
final var propName = propDef.get("propertyName").toString();
|
||||
final var propUnit = ofNullable(propDef.get("unit")).map(u -> " " + u).orElse("");
|
||||
final var totalValue = ofNullable(assetEntity.getSubBookingItems()).orElse(emptyList())
|
||||
.stream()
|
||||
.filter(subItem -> subTypes.contains(subItem.getType()))
|
||||
.map(subItem -> toInteger(subItem.getResources().get(propName)))
|
||||
.reduce(0, Integer::sum);
|
||||
final var maxValue = toInteger(assetEntity.getResources().get(propName));
|
||||
return totalValue > maxValue
|
||||
? "total %s is %d%s exceeds max total %s %d%s".formatted(
|
||||
propName, totalValue, propUnit, propName, maxValue, propUnit)
|
||||
: null;
|
||||
}
|
||||
|
||||
protected List<String> validateParentEntities(final HsBookingItemEntity bookingItem) {
|
||||
return bookingItem.getParentItem() != null
|
||||
? HsBookingItemEntityValidators.validate(bookingItem.getParentItem())
|
||||
: emptyList();
|
||||
}
|
||||
|
||||
private Integer toInteger(final Object value) {
|
||||
return value == null ? 0 : (Integer) value;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.validation;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.AbstractMap.SimpleImmutableEntry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -15,10 +14,6 @@ public abstract class HsPropertyValidator<T> {
|
||||
final String propertyName;
|
||||
private Boolean required;
|
||||
|
||||
public static <K, V> Map.Entry<K, V> defType(K k, V v) {
|
||||
return new SimpleImmutableEntry<>(k, v);
|
||||
}
|
||||
|
||||
public HsPropertyValidator<T> required() {
|
||||
required = Boolean.TRUE;
|
||||
return this;
|
||||
|
@ -5,10 +5,11 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
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.HsBookingItemEntityValidators.valid;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
@ -39,6 +40,6 @@ class HsBookingItemEntityValidatorsUnitTest {
|
||||
final var result = HsBookingItemEntityValidators.types();
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(CLOUD_SERVER, MANAGED_SERVER, MANAGED_WEBSPACE);
|
||||
assertThat(result).containsExactlyInAnyOrder(PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER, MANAGED_WEBSPACE);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,12 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.List.of;
|
||||
import static java.util.Map.entry;
|
||||
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.HsBookingItemEntityValidators.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -15,7 +19,6 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
@Test
|
||||
void validatesProperties() {
|
||||
// given
|
||||
final var validator = HsBookingItemEntityValidators.forType(CLOUD_SERVER);
|
||||
final var cloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(Map.ofEntries(
|
||||
@ -28,7 +31,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(cloudServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidators.validate(cloudServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'resources.SLA-EMail' is not expected but is set to 'true'");
|
||||
@ -48,4 +51,53 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
"{type=integer, propertyName=Traffic, required=true, unit=GB, min=250, max=10000, step=250}",
|
||||
"{type=enumeration, propertyName=SLA-Infrastructure, required=false, values=[BASIC, EXT8H, EXT4H, EXT2H]}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesExceedingPropertyTotals() {
|
||||
// given
|
||||
final var subCloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build();
|
||||
final HsBookingItemEntity subManagedServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 3),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 3000)
|
||||
))
|
||||
.build();
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(PRIVATE_CLOUD)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
subManagedServerBookingItemEntity,
|
||||
subCloudServerBookingItemEntity
|
||||
))
|
||||
.build();
|
||||
subManagedServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidators.validate(subCloudServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"total CPUs is 5 exceeds max total CPUs 4",
|
||||
"total RAM is 30 GB exceeds max total RAM 20 GB",
|
||||
"total SSD is 150 GB exceeds max total SSD 100 GB",
|
||||
"total Traffic is 5500 GB exceeds max total Traffic 5000 GB"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,12 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.List.of;
|
||||
import static java.util.Map.entry;
|
||||
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.HsBookingItemEntityValidators.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -15,7 +19,6 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
@Test
|
||||
void validatesProperties() {
|
||||
// given
|
||||
final var validator = HsBookingItemEntityValidators.forType(MANAGED_SERVER);
|
||||
final var mangedServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(Map.ofEntries(
|
||||
@ -28,7 +31,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidators.validate(mangedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'resources.SLA-EMail' is expected to be false because resources.SLA-Platform=BASIC but is true");
|
||||
@ -53,4 +56,53 @@ class HsManagedServerBookingItemValidatorUnitTest {
|
||||
"{type=boolean, propertyName=SLA-Office, required=false, falseIf={SLA-Platform=BASIC}}",
|
||||
"{type=boolean, propertyName=SLA-Web, required=false, falseIf={SLA-Platform=BASIC}}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesExceedingPropertyTotals() {
|
||||
// given
|
||||
final var subCloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build();
|
||||
final HsBookingItemEntity subManagedServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 3),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 3000)
|
||||
))
|
||||
.build();
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(PRIVATE_CLOUD)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
subManagedServerBookingItemEntity,
|
||||
subCloudServerBookingItemEntity
|
||||
))
|
||||
.build();
|
||||
subManagedServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidators.validate(subManagedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"total CPUs is 5 exceeds max total CPUs 4",
|
||||
"total RAM is 30 GB exceeds max total RAM 20 GB",
|
||||
"total SSD is 150 GB exceeds max total SSD 100 GB",
|
||||
"total Traffic is 5500 GB exceeds max total Traffic 5000 GB"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import java.util.Map;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidators.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedWebspaceBookingItemValidatorUnitTest {
|
||||
@ -25,10 +24,9 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
|
||||
entry("SLA-EMail", true)
|
||||
))
|
||||
.build();
|
||||
final var validator = forType(mangedServerBookingItemEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidators.validate(mangedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
@ -40,7 +38,7 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsBookingItemEntityValidators.forType(MANAGED_WEBSPACE);
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
|
@ -0,0 +1,102 @@
|
||||
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;
|
||||
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 org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsPrivateCloudBookingItemValidatorTest {
|
||||
|
||||
@Test
|
||||
void validatesPropertyTotals() {
|
||||
// given
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(PRIVATE_CLOUD)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build(),
|
||||
HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidators.validate(privateCloudBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesExceedingPropertyTotals() {
|
||||
// given
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(PRIVATE_CLOUD)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 3),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 3000)
|
||||
))
|
||||
.build(),
|
||||
HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidators.validate(privateCloudBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"total CPUs is 5 exceeds max total CPUs 4",
|
||||
"total RAM is 30 GB exceeds max total RAM 20 GB",
|
||||
"total SSD is 150 GB exceeds max total SSD 100 GB",
|
||||
"total Traffic is 5500 GB exceeds max total Traffic 5000 GB"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -20,7 +20,6 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
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.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
@ -7,7 +7,7 @@ import java.util.Map;
|
||||
|
||||
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.validators.HsHostingAssetEntityValidators.forType;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
|
@ -6,11 +6,11 @@ import org.junit.jupiter.api.Test;
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidators.valid;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.valid;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
class HsHostingAssetEntityValidatorsUnitTest {
|
||||
class HsHostingAssetEntityValidatorUnitTest {
|
||||
|
||||
@Test
|
||||
void validThrowsException() {
|
@ -7,7 +7,7 @@ import java.util.Map;
|
||||
|
||||
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.validators.HsHostingAssetEntityValidators.forType;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
|
@ -30,7 +30,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
@Test
|
||||
void validatesIdentifier() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
@ -47,7 +47,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
@Test
|
||||
void validatesUnknownProperties() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
@ -67,7 +67,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
@Test
|
||||
void validatesValidEntity() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
|
Loading…
Reference in New Issue
Block a user