hosting-asset-validation-beyond-property-validators #65
@ -34,6 +34,7 @@ import jakarta.persistence.OneToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import jakarta.persistence.Transient;
|
||||
import jakarta.persistence.Version;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.util.HashMap;
|
||||
@ -92,6 +93,7 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject {
|
||||
@JoinColumn(name = "parentitemuuid")
|
||||
private HsBookingItemEntity parentItem;
|
||||
|
||||
@NotNull
|
||||
@Column(name = "type")
|
||||
@Enumerated(EnumType.STRING)
|
||||
private HsBookingItemType type;
|
||||
|
@ -0,0 +1,23 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
class HsCloudServerHostingAssetValidator extends HsHostingAssetEntityValidator {
|
||||
|
||||
HsCloudServerHostingAssetValidator() {
|
||||
super(
|
||||
BookingItem.mustBeOfType(HsBookingItemType.CLOUD_SERVER),
|
||||
ParentAsset.mustBeNull(),
|
||||
AssignedToAsset.mustBeNull(),
|
||||
AlarmContact.isOptional(),
|
||||
NO_EXTRA_PROPERTIES);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
return Pattern.compile("^vm[0-9][0-9][0-9][0-9]$");
|
||||
}
|
||||
}
|
@ -1,35 +1,80 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
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.office.contact.HsOfficeContactEntity;
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
import net.hostsharing.hsadminng.hs.validation.ValidatableProperty;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Optional.ofNullable;
|
||||
|
||||
public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity> {
|
||||
public abstract class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity> {
|
||||
|
||||
public HsHostingAssetEntityValidator(final ValidatableProperty<?>... properties) {
|
||||
static final ValidatableProperty<?>[] NO_EXTRA_PROPERTIES = new ValidatableProperty<?>[0];
|
||||
|
||||
private final HsHostingAssetEntityValidator.BookingItem bookingItemValidation;
|
||||
private final HsHostingAssetEntityValidator.ParentAsset parentAssetValidation;
|
||||
private final HsHostingAssetEntityValidator.AssignedToAsset assignedToAssetValidation;
|
||||
private final HsHostingAssetEntityValidator.AlarmContact alarmContactValidation;
|
||||
|
||||
HsHostingAssetEntityValidator(
|
||||
@NotNull final BookingItem bookingItemValidation,
|
||||
@NotNull final ParentAsset parentAssetValidation,
|
||||
@NotNull final AssignedToAsset assignedToAssetValidation,
|
||||
@NotNull final AlarmContact alarmContactValidation,
|
||||
final ValidatableProperty<?>... properties) {
|
||||
super(properties);
|
||||
this.bookingItemValidation = bookingItemValidation;
|
||||
this.parentAssetValidation = parentAssetValidation;
|
||||
this.assignedToAssetValidation = assignedToAssetValidation;
|
||||
this.alarmContactValidation = alarmContactValidation;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> validate(final HsHostingAssetEntity assetEntity) {
|
||||
return sequentiallyValidate(
|
||||
() -> validateProperties(assetEntity),
|
||||
() -> validateEntityReferences(assetEntity),
|
||||
() -> validateIdentifierPattern(assetEntity), // might need proper parentAsset or billingItem
|
||||
() -> optionallyValidate(assetEntity.getBookingItem()),
|
||||
() -> optionallyValidate(assetEntity.getParentAsset()),
|
||||
() -> validateAgainstSubEntities(assetEntity)
|
||||
);
|
||||
}
|
||||
|
||||
private List<String> validateEntityReferences(final HsHostingAssetEntity assetEntity) {
|
||||
return Stream.of(
|
||||
validateReferencedEntity(assetEntity, "bookingItem", bookingItemValidation::validate),
|
||||
validateReferencedEntity(assetEntity, "parentAsset", parentAssetValidation::validate),
|
||||
validateReferencedEntity(assetEntity, "assignedToAsset", assignedToAssetValidation::validate),
|
||||
validateReferencedEntity(assetEntity, "alarmContact", alarmContactValidation::validate),
|
||||
validateProperties(assetEntity))
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(List::stream)
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
|
||||
private List<String> validateReferencedEntity(
|
||||
final HsHostingAssetEntity assetEntity,
|
||||
final String referenceFieldName,
|
||||
final BiFunction<HsHostingAssetEntity, String, List<String>> validator) {
|
||||
return enrich(prefix(assetEntity.toShortString()), validator.apply(assetEntity, referenceFieldName));
|
||||
}
|
||||
|
||||
private List<String> validateProperties(final HsHostingAssetEntity assetEntity) {
|
||||
return enrich(prefix(assetEntity.toShortString(), "config"), validateProperties(assetEntity.getConfig()));
|
||||
}
|
||||
@ -73,4 +118,120 @@ public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAs
|
||||
propName, maxValue, propUnit, propName, totalValue, propUnit)
|
||||
: null;
|
||||
}
|
||||
|
||||
private List<String> validateIdentifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
final var expectedIdentifierPattern = identifierPattern(assetEntity);
|
||||
if (!expectedIdentifierPattern.matcher(assetEntity.getIdentifier()).matches()) {
|
||||
return List.of("'identifier' expected to match '"+expectedIdentifierPattern+"', but is '" + assetEntity.getIdentifier() + "'");
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
protected abstract Pattern identifierPattern(HsHostingAssetEntity assetEntity);
|
||||
|
||||
static abstract class ReferenceValidator<S, T> {
|
||||
|
||||
private final Policy policy;
|
||||
private final T subEntityType;
|
||||
private final Function<HsHostingAssetEntity, S> subEntityGetter;
|
||||
private final Function<S,T> subEntityTypeGetter;
|
||||
|
||||
public ReferenceValidator(
|
||||
final Policy policy,
|
||||
final T subEntityType,
|
||||
final Function<HsHostingAssetEntity, S> subEntityGetter,
|
||||
final Function<S, T> subEntityTypeGetter) {
|
||||
this.policy = policy;
|
||||
this.subEntityType = subEntityType;
|
||||
this.subEntityGetter = subEntityGetter;
|
||||
this.subEntityTypeGetter = subEntityTypeGetter;
|
||||
}
|
||||
|
||||
public ReferenceValidator(
|
||||
final Policy policy,
|
||||
final Function<HsHostingAssetEntity, S> subEntityGetter) {
|
||||
this.policy = policy;
|
||||
this.subEntityType = null;
|
||||
this.subEntityGetter = subEntityGetter;
|
||||
this.subEntityTypeGetter = e -> null;
|
||||
}
|
||||
|
||||
enum Policy {
|
||||
OPTIONAL, FORBIDDEN, REQUIRED
|
||||
}
|
||||
|
||||
List<String> validate(final HsHostingAssetEntity assetEntity, final String referenceFieldName) {
|
||||
|
||||
final var subEntity = subEntityGetter.apply(assetEntity);
|
||||
if (policy == Policy.REQUIRED && subEntity == null) {
|
||||
return List.of(referenceFieldName + "' must not be null but is null");
|
||||
}
|
||||
if (policy == Policy.FORBIDDEN && subEntity != null) {
|
||||
return List.of(referenceFieldName + "' must not be null but is set to "+ assetEntity.getBookingItem().toShortString());
|
||||
}
|
||||
final var subItemType = subEntity != null ? subEntityTypeGetter.apply(subEntity) : null;
|
||||
if (subEntityType != null && subItemType != subEntityType) {
|
||||
return List.of(referenceFieldName + "' must be of type " + subEntityType + " but is of type " + subItemType);
|
||||
}
|
||||
return emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
static class BookingItem extends ReferenceValidator<HsBookingItemEntity, HsBookingItemType> {
|
||||
|
||||
BookingItem(final Policy policy, final HsBookingItemType bookingItemType) {
|
||||
super(policy, bookingItemType, HsHostingAssetEntity::getBookingItem, HsBookingItemEntity::getType);
|
||||
}
|
||||
|
||||
static BookingItem mustBeNull() {
|
||||
return new BookingItem(Policy.FORBIDDEN, null);
|
||||
}
|
||||
|
||||
static BookingItem mustBeOfType(final HsBookingItemType hsBookingItemType) {
|
||||
return new BookingItem(Policy.REQUIRED, hsBookingItemType);
|
||||
}
|
||||
}
|
||||
|
||||
static class ParentAsset extends ReferenceValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
ParentAsset(final ReferenceValidator.Policy policy, final HsHostingAssetType parentAssetType) {
|
||||
super(policy, parentAssetType, HsHostingAssetEntity::getParentAsset, HsHostingAssetEntity::getType);
|
||||
}
|
||||
|
||||
static ParentAsset mustBeNull() {
|
||||
return new ParentAsset(Policy.FORBIDDEN, null);
|
||||
}
|
||||
|
||||
static ParentAsset mustBeOfType(final HsHostingAssetType hostingAssetType) {
|
||||
return new ParentAsset(Policy.REQUIRED, hostingAssetType);
|
||||
}
|
||||
|
||||
static ParentAsset mustBeNullOrOfType(final HsHostingAssetType hostingAssetType) {
|
||||
return new ParentAsset(Policy.OPTIONAL, hostingAssetType);
|
||||
}
|
||||
}
|
||||
|
||||
static class AssignedToAsset extends ReferenceValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
AssignedToAsset(final ReferenceValidator.Policy policy, final HsHostingAssetType assignedToAssetType) {
|
||||
super(policy, assignedToAssetType, HsHostingAssetEntity::getAssignedToAsset, HsHostingAssetEntity::getType);
|
||||
}
|
||||
|
||||
static AssignedToAsset mustBeNull() {
|
||||
return new AssignedToAsset(Policy.FORBIDDEN, null);
|
||||
}
|
||||
}
|
||||
|
||||
static class AlarmContact extends ReferenceValidator<HsOfficeContactEntity, Enum<?>> {
|
||||
|
||||
AlarmContact(final ReferenceValidator.Policy policy) {
|
||||
super(policy, HsHostingAssetEntity::getAlarmContact);
|
||||
}
|
||||
|
||||
static AlarmContact isOptional() {
|
||||
return new AlarmContact(Policy.OPTIONAL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -14,10 +14,10 @@ public class HsHostingAssetEntityValidatorRegistry {
|
||||
|
||||
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity>> validators = new HashMap<>();
|
||||
static {
|
||||
register(CLOUD_SERVER, new HsHostingAssetEntityValidator());
|
||||
register(CLOUD_SERVER, new HsCloudServerHostingAssetValidator());
|
||||
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
|
||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
||||
register(UNIX_USER, new HsHostingAssetEntityValidator());
|
||||
register(UNIX_USER, new HsUnixUserHostingAssetValidator());
|
||||
}
|
||||
|
||||
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity> validator) {
|
||||
|
@ -1,5 +1,10 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.validation.BooleanProperty.booleanProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.EnumerationProperty.enumerationProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerProperty.integerProperty;
|
||||
@ -8,6 +13,11 @@ class HsManagedServerHostingAssetValidator extends HsHostingAssetEntityValidator
|
||||
|
||||
public HsManagedServerHostingAssetValidator() {
|
||||
super(
|
||||
BookingItem.mustBeOfType(HsBookingItemType.MANAGED_SERVER),
|
||||
ParentAsset.mustBeNull(), // until we introduce a hosting asset for 'HOST'
|
||||
AssignedToAsset.mustBeNull(),
|
||||
AlarmContact.isOptional(), // hostmaster alert address is implicitly added
|
||||
|
||||
// monitoring
|
||||
integerProperty("monit_max_cpu_usage").unit("%").min(10).max(100).withDefault(92),
|
||||
integerProperty("monit_max_ram_usage").unit("%").min(10).max(100).withDefault(92),
|
||||
@ -15,7 +25,6 @@ class HsManagedServerHostingAssetValidator extends HsHostingAssetEntityValidator
|
||||
integerProperty("monit_min_free_ssd").min(1).max(1000).withDefault(5),
|
||||
integerProperty("monit_max_hdd_usage").unit("%").min(10).max(100).withDefault(95),
|
||||
integerProperty("monit_min_free_hdd").min(1).max(4000).withDefault(10),
|
||||
// stringProperty("monit_alarm_email").unit("GB").optional() TODO.impl: via Contact?
|
||||
|
||||
// other settings
|
||||
// booleanProperty("fastcgi_small").withDefault(false), TODO.spec: clarify Salt-Grains
|
||||
@ -45,4 +54,9 @@ class HsManagedServerHostingAssetValidator extends HsHostingAssetEntityValidator
|
||||
booleanProperty("software-imagemagick-ghostscript").withDefault(false)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
return Pattern.compile("^vm[0-9][0-9][0-9][0-9]$");
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,22 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
class HsManagedWebspaceHostingAssetValidator extends HsHostingAssetEntityValidator {
|
||||
public HsManagedWebspaceHostingAssetValidator() {
|
||||
super(BookingItem.mustBeOfType(HsBookingItemType.MANAGED_WEBSPACE),
|
||||
ParentAsset.mustBeOfType(HsHostingAssetType.MANAGED_SERVER), // the (shared or private) ManagedServer
|
||||
AssignedToAsset.mustBeNull(),
|
||||
AlarmContact.isOptional(), // hostmaster alert address is implicitly added
|
||||
NO_EXTRA_PROPERTIES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> validate(final HsHostingAssetEntity assetEntity) {
|
||||
return Stream.of(validateIdentifierPattern(assetEntity), super.validate(assetEntity))
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<String> validateIdentifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
final var expectedIdentifierPattern = "^" + assetEntity.getParentAsset().getBookingItem().getProject().getDebitor().getDefaultPrefix() + "[0-9][0-9]$";
|
||||
if ( !assetEntity.getIdentifier().matches(expectedIdentifierPattern)) {
|
||||
return List.of("'identifier' expected to match '"+expectedIdentifierPattern+"', but is '" + assetEntity.getIdentifier() + "'");
|
||||
}
|
||||
return Collections.emptyList();
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
hsh-michaelhoennig marked this conversation as resolved
|
||||
return Pattern.compile("^" + assetEntity.getParentAsset().getBookingItem().getProject().getDebitor().getDefaultPrefix() + "[0-9][0-9]$");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
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 java.util.regex.Pattern;
|
||||
|
||||
class HsUnixUserHostingAssetValidator extends HsHostingAssetEntityValidator {
|
||||
|
||||
HsUnixUserHostingAssetValidator() {
|
||||
super(BookingItem.mustBeNull(),
|
||||
ParentAsset.mustBeOfType(HsHostingAssetType.MANAGED_WEBSPACE),
|
||||
AssignedToAsset.mustBeNull(),
|
||||
AlarmContact.isOptional(), // TODO.spec: for quota notifications
|
||||
NO_EXTRA_PROPERTIES); // TODO.spec: yet to be specified
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Pattern identifierPattern(final HsHostingAssetEntity assetEntity) {
|
||||
final var webspaceIdentifier = assetEntity.getParentAsset().getIdentifier();
|
||||
return Pattern.compile("^"+webspaceIdentifier+"$|^"+webspaceIdentifier+"-[a-z0-9]+$");
|
||||
}
|
||||
}
|
@ -12,13 +12,21 @@ import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.
|
||||
@UtilityClass
|
||||
public class TestHsBookingItem {
|
||||
|
||||
public static final HsBookingItemEntity TEST_BOOKING_ITEM = HsBookingItemEntity.builder()
|
||||
public static final HsBookingItemEntity TEST_MANAGED_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
|
||||
.project(TEST_PROJECT)
|
||||
.caption("test booking item")
|
||||
.type(HsBookingItemType.MANAGED_SERVER)
|
||||
.caption("test project booking item")
|
||||
.resources(Map.ofEntries(
|
||||
entry("someThing", 1),
|
||||
entry("anotherThing", "blue")
|
||||
))
|
||||
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
|
||||
.build();
|
||||
|
||||
public static final HsBookingItemEntity TEST_CLOUD_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
|
||||
.project(TEST_PROJECT)
|
||||
.type(HsBookingItemType.CLOUD_SERVER)
|
||||
.caption("test cloud server booking item")
|
||||
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
|
||||
.build();
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
|
||||
import static net.hostsharing.hsadminng.mapper.PatchMap.patchMap;
|
||||
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||
@ -70,7 +70,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
protected HsHostingAssetEntity newInitialEntity() {
|
||||
final var entity = new HsHostingAssetEntity();
|
||||
entity.setUuid(INITIAL_BOOKING_ITEM_UUID);
|
||||
entity.setBookingItem(TEST_BOOKING_ITEM);
|
||||
entity.setBookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM);
|
||||
entity.getConfig().putAll(KeyValueMap.from(INITIAL_CONFIG));
|
||||
entity.setCaption(INITIAL_CAPTION);
|
||||
entity.setAlarmContact(givenInitialContact);
|
||||
|
@ -5,13 +5,13 @@ import org.junit.jupiter.api.Test;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsHostingAssetEntityUnitTest {
|
||||
|
||||
final HsHostingAssetEntity givenParentAsset = HsHostingAssetEntity.builder()
|
||||
.bookingItem(TEST_BOOKING_ITEM)
|
||||
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
|
||||
.type(HsHostingAssetType.MANAGED_SERVER)
|
||||
.identifier("vm1234")
|
||||
.caption("some managed asset")
|
||||
@ -21,7 +21,7 @@ class HsHostingAssetEntityUnitTest {
|
||||
entry("HDD-storage", 2048)))
|
||||
.build();
|
||||
final HsHostingAssetEntity givenWebspace = HsHostingAssetEntity.builder()
|
||||
.bookingItem(TEST_BOOKING_ITEM)
|
||||
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
|
||||
.type(HsHostingAssetType.MANAGED_WEBSPACE)
|
||||
.parentAsset(givenParentAsset)
|
||||
.identifier("xyz00")
|
||||
|
@ -6,6 +6,7 @@ import org.junit.jupiter.api.Test;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@ -28,7 +29,28 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
final var result = validator.validate(cloudServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'CLOUD_SERVER:vm1234.config.RAM' is not expected but is set to '2000'");
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'CLOUD_SERVER:vm1234.bookingItem' must not be null but is null",
|
||||
"'CLOUD_SERVER:vm1234.config.RAM' is not expected but is set to '2000'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesInvalidIdentifier() {
|
||||
// given
|
||||
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.identifier("xyz99")
|
||||
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
|
||||
.build();
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(cloudServerHostingAssetEntity.getType());
|
||||
|
||||
|
||||
// when
|
||||
final var result = validator.validate(cloudServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'identifier' expected to match '^vm[0-9][0-9][0-9][0-9]$', but is 'xyz99'");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1,6 +1,9 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
@ -16,12 +19,17 @@ class HsHostingAssetEntityValidatorUnitTest {
|
||||
final var managedServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.identifier("vm1234")
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_SERVER).build())
|
||||
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_SERVER).build())
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = catchThrowable( ()-> HsHostingAssetEntityValidatorRegistry.validated(managedServerHostingAssetEntity));
|
||||
|
||||
// then
|
||||
assertThat(result).isNull(); // all required properties have defaults
|
||||
assertThat(result.getMessage()).contains(
|
||||
"'MANAGED_SERVER:vm1234.parentAsset' must not be null but is set to D-???????-?:null",
|
||||
"'MANAGED_SERVER:vm1234.assignedToAsset' must not be null but is set to D-???????-?:null"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +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.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@ -17,6 +19,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.identifier("vm1234")
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_SERVER).build())
|
||||
.config(Map.ofEntries(
|
||||
entry("monit_max_hdd_usage", "90"),
|
||||
entry("monit_max_cpu_usage", 2),
|
||||
@ -30,8 +33,28 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'MANAGED_SERVER:vm1234.parentAsset' must not be null but is set to D-???????-?:null",
|
||||
"'MANAGED_SERVER:vm1234.assignedToAsset' must not be null but is set to D-???????-?:null",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_cpu_usage' is expected to be >= 10 but is 2",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_ram_usage' is expected to be <= 100 but is 101",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_hdd_usage' is expected to be of type class java.lang.Integer, but is of type 'String'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesInvalidIdentifier() {
|
||||
// given
|
||||
final var mangedServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.identifier("xyz00")
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_SERVER).build())
|
||||
.build();
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'identifier' expected to match '^vm[0-9][0-9][0-9][0-9]$', but is 'xyz00'");
|
||||
}
|
||||
}
|
||||
|
@ -40,11 +40,12 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void validatesIdentifier() {
|
||||
void validatesIdentifierAndReferencedEntities() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
.identifier("xyz00")
|
||||
.build();
|
||||
@ -62,6 +63,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
.identifier("abc00")
|
||||
.config(Map.ofEntries(
|
||||
@ -82,6 +84,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
.identifier("abc00")
|
||||
.build();
|
||||
|
@ -0,0 +1,27 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsUnixUserHostingAssetValidatorUnitTest {
|
||||
|
||||
@Test
|
||||
void validatesInvalidIdentifier() {
|
||||
// given
|
||||
final var unixUserHostingAsset = HsHostingAssetEntity.builder()
|
||||
.type(UNIX_USER)
|
||||
.identifier("abc")
|
||||
.build();
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
|
||||
|
||||
|
||||
// when
|
||||
final var result = validator.validate(unixUserHostingAsset);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'identifier' expected to match '^vm[0-9][0-9][0-9][0-9]$', but is 'xyz99'");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user
nur bei neu angelegten Objekten prüfen