hosting-asset-validation-baseline #56
@ -17,6 +17,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntityValidators.valid;
|
||||
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
|
||||
|
||||
@RestController
|
||||
@ -56,7 +57,7 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
|
||||
final var entityToSave = mapper.map(body, HsBookingItemEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||
|
||||
final var saved = bookingItemRepo.save(entityToSave);
|
||||
final var saved = bookingItemRepo.save(valid(entityToSave));
|
||||
|
||||
final var uri =
|
||||
MvcUriComponentsBuilder.fromController(getClass())
|
||||
@ -111,7 +112,7 @@ public class HsBookingItemController implements HsBookingItemsApi {
|
||||
|
||||
new HsBookingItemEntityPatcher(current).apply(body);
|
||||
|
||||
final var saved = bookingItemRepo.save(current);
|
||||
final var saved = bookingItemRepo.save(valid(current));
|
||||
final var mapped = mapper.map(saved, HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
@ -143,6 +143,11 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject, Validatab
|
||||
":" + caption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertiesName() {
|
||||
return "resources";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getProperties() {
|
||||
return resources;
|
||||
|
@ -9,13 +9,21 @@ 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;
|
||||
|
||||
@UtilityClass
|
||||
public class HsBookingItemEntityValidators {
|
||||
|
||||
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItemEntity, HsBookingItemType>> validators = new HashMap<>();
|
||||
static {
|
||||
register(CLOUD_SERVER, new HsCloudServerBookingItemValidator());
|
||||
register(MANAGED_SERVER, new HsManagedServerBookingItemValidator());
|
||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceBookingItemValidator());
|
||||
}
|
||||
|
||||
public static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItemEntity, HsBookingItemType> validator) {
|
||||
private static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItemEntity, HsBookingItemType> validator) {
|
||||
stream(validator.propertyValidators).forEach( entry -> {
|
||||
entry.verifyConsistency(Map.entry(type, validator));
|
||||
});
|
||||
|
@ -0,0 +1,20 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.validation.EnumerationPropertyValidator.enumerationProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
||||
|
||||
class HsCloudServerBookingItemValidator extends HsEntityValidator<HsBookingItemEntity, HsBookingItemType> {
|
||||
|
||||
HsCloudServerBookingItemValidator() {
|
||||
super(
|
||||
integerProperty("CPUs").min(1).max(32).required(),
|
||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required(),
|
||||
enumerationProperty("SLA-Infrastructure").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional()
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
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;
|
||||
|
||||
class HsManagedServerBookingItemValidator extends HsEntityValidator<HsBookingItemEntity, HsBookingItemType> {
|
||||
|
||||
HsManagedServerBookingItemValidator() {
|
||||
super(
|
||||
integerProperty("CPUs").min(1).max(32).required(),
|
||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required(),
|
||||
enumerationProperty("SLA-Platform").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional(),
|
||||
booleanProperty("SLA-EMail").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-Maria").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-PgSQL").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-Office").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-Web").falseIf("SLA-Platform", "BASIC").optional()
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
class HsManagedWebspaceBookingItemValidator extends HsEntityValidator<HsBookingItemEntity, HsBookingItemType> {
|
||||
|
||||
public HsManagedWebspaceBookingItemValidator() {
|
||||
super(
|
||||
integerProperty("SSD").unit("GB").min(1).max(100).step(1).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(250).step(10).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(10).max(1000).step(10).required(),
|
||||
enumerationProperty("SLA-Platform").values("BASIC", "EXT24H").optional(),
|
||||
integerProperty("Daemons").min(0).max(10).optional(),
|
||||
booleanProperty("Online Office Server").optional()
|
||||
);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.validation.EnumerationPropertyValidator.enumerationProperty;
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
||||
|
||||
@Component
|
||||
class HsCloudServerAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
static {
|
||||
HsHostingAssetEntityValidators.register(CLOUD_SERVER, new HsCloudServerAssetValidator());
|
||||
}
|
||||
|
||||
public HsCloudServerAssetValidator() {
|
||||
super(
|
||||
integerProperty("CPUs").min(1).max(32).required(),
|
||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required(),
|
||||
enumerationProperty("SLA-Infrastructure").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional()
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
||||
|
||||
class HsCloudServerHostingAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
public HsCloudServerHostingAssetValidator() {
|
||||
super(
|
||||
integerProperty("CPUs").min(1).max(32).required(),
|
||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required()
|
||||
);
|
||||
}
|
||||
}
|
@ -114,6 +114,11 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata
|
||||
PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper; }, config).assign(newConfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPropertiesName() {
|
||||
return "config";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getProperties() {
|
||||
return config;
|
||||
|
@ -9,24 +9,32 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
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 {
|
||||
|
||||
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType>> validators = new HashMap<>();
|
||||
static {
|
||||
register(CLOUD_SERVER, new HsCloudServerHostingAssetValidator());
|
||||
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
|
||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
||||
}
|
||||
|
||||
public static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> validator) {
|
||||
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> validator) {
|
||||
stream(validator.propertyValidators).forEach( entry -> {
|
||||
entry.verifyConsistency(Map.entry(type, validator));
|
||||
});
|
||||
validators.put(type, validator);
|
||||
}
|
||||
|
||||
public static HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> forType(final Enum<HsHostingAssetType> type) {
|
||||
static HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> forType(final Enum<HsHostingAssetType> type) {
|
||||
return validators.get(type);
|
||||
}
|
||||
|
||||
public static Set<? extends Enum<?>> types() {
|
||||
static Set<? extends Enum<?>> types() {
|
||||
return validators.keySet();
|
||||
}
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||
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;
|
||||
|
||||
@Component
|
||||
class HsManagedServerAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
static {
|
||||
HsHostingAssetEntityValidators.register(MANAGED_SERVER, new HsManagedServerAssetValidator());
|
||||
}
|
||||
|
||||
public HsManagedServerAssetValidator() {
|
||||
super(
|
||||
integerProperty("CPUs").min(1).max(32).required(),
|
||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required(),
|
||||
enumerationProperty("SLA-Platform").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional(),
|
||||
booleanProperty("SLA-EMail").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-Maria").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-PgSQL").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-Office").falseIf("SLA-Platform", "BASIC").optional(),
|
||||
booleanProperty("SLA-Web").falseIf("SLA-Platform", "BASIC").optional()
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
||||
|
||||
class HsManagedServerHostingAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
public HsManagedServerHostingAssetValidator() {
|
||||
super(
|
||||
integerProperty("CPUs").min(1).max(32).required(),
|
||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required()
|
||||
);
|
||||
}
|
||||
}
|
@ -1,40 +1,32 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||
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;
|
||||
|
||||
@Component
|
||||
class HsManagedWebspaceAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
|
||||
static {
|
||||
HsHostingAssetEntityValidators.register(MANAGED_WEBSPACE, new HsManagedWebspaceAssetValidator());
|
||||
}
|
||||
|
||||
public HsManagedWebspaceAssetValidator() {
|
||||
class HsManagedWebspaceHostingAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||
public HsManagedWebspaceHostingAssetValidator() {
|
||||
super(
|
||||
integerProperty("SSD").unit("GB").min(1).max(100).step(1).required(),
|
||||
integerProperty("HDD").unit("GB").min(0).max(250).step(10).optional(),
|
||||
integerProperty("Traffic").unit("GB").min(10).max(1000).step(10).required(),
|
||||
enumerationProperty("SLA-Platform").values("BASIC", "EXT24H").optional(),
|
||||
integerProperty("Daemons").min(0).max(10).optional(),
|
||||
booleanProperty("Online Office Server").optional()
|
||||
integerProperty("Traffic").unit("GB").min(10).max(1000).step(10).required()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> validate(final HsHostingAssetEntity assetEntity) {
|
||||
final var result = super.validate(assetEntity);
|
||||
validateIdentifierPattern(result, assetEntity);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void validateIdentifierPattern(final List<String> result, final HsHostingAssetEntity assetEntity) {
|
||||
final var expectedIdentifierPattern = "^" + assetEntity.getParentAsset().getBookingItem().getDebitor().getDefaultPrefix() + "[0-9][0-9]$";
|
||||
if ( !assetEntity.getIdentifier().matches(expectedIdentifierPattern)) {
|
||||
result.add("'identifier' expected to match '"+expectedIdentifierPattern+"', but is '" + assetEntity.getIdentifier() + "'");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -26,11 +26,11 @@ public class BooleanPropertyValidator extends HsPropertyValidator<Boolean> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validate(final ArrayList<String> result, final Boolean propValue, final Map<String, Object> props) {
|
||||
protected void validate(final ArrayList<String> result, final String propertiesName, final Boolean propValue, final Map<String, Object> props) {
|
||||
if (falseIf != null && !Objects.equals(props.get(falseIf.getKey()), falseIf.getValue())) {
|
||||
if (propValue) {
|
||||
result.add("'config." + propertyName + "' is expected to be false because " +
|
||||
"config." + falseIf.getKey()+ "=" + falseIf.getValue() + " but is " + propValue);
|
||||
result.add("'"+propertiesName+"." + propertyName + "' is expected to be false because " +
|
||||
propertiesName+"." + falseIf.getKey()+ "=" + falseIf.getValue() + " but is " + propValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ public class EnumerationPropertyValidator extends HsPropertyValidator<String> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validate(final ArrayList<String> result, final String propValue, final Map<String, Object> props) {
|
||||
protected void validate(final ArrayList<String> result, final String propertiesName, final String propValue, final Map<String, Object> props) {
|
||||
if (Arrays.stream(values).noneMatch(v -> v.equals(propValue))) {
|
||||
result.add("'config." + propertyName + "' is expected to be one of " + Arrays.toString(values) + " but is '" + propValue + "'");
|
||||
result.add("'"+propertiesName+"." + propertyName + "' is expected to be one of " + Arrays.toString(values) + " but is '" + propValue + "'");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,11 +23,11 @@ public class HsEntityValidator<E extends Validatable<E, T>, T extends Enum<T>> {
|
||||
final var result = new ArrayList<String>();
|
||||
assetEntity.getProperties().keySet().forEach( givenPropName -> {
|
||||
if (stream(propertyValidators).map(pv -> pv.propertyName).noneMatch(propName -> propName.equals(givenPropName))) {
|
||||
result.add("'config." + givenPropName + "' is not expected but is '" +assetEntity.getProperties().get(givenPropName) + "'");
|
||||
result.add("'"+assetEntity.getPropertiesName()+"." + givenPropName + "' is not expected but is set to '" +assetEntity.getProperties().get(givenPropName) + "'");
|
||||
}
|
||||
});
|
||||
stream(propertyValidators).forEach(pv -> {
|
||||
result.addAll(pv.validate(assetEntity.getProperties()));
|
||||
result.addAll(pv.validate(assetEntity.getPropertiesName(), assetEntity.getProperties()));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
@ -29,27 +29,27 @@ public abstract class HsPropertyValidator<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public final List<String> validate(final Map<String, Object> props) {
|
||||
public final List<String> validate(final String propertiesName, final Map<String, Object> props) {
|
||||
final var result = new ArrayList<String>();
|
||||
final var propValue = props.get(propertyName);
|
||||
if (propValue == null) {
|
||||
if (required) {
|
||||
result.add("'config." + propertyName + "' is required but missing");
|
||||
result.add("'"+propertiesName+"." + propertyName + "' is required but missing");
|
||||
}
|
||||
}
|
||||
if (propValue != null){
|
||||
if ( type.isInstance(propValue)) {
|
||||
//noinspection unchecked
|
||||
validate(result, (T) propValue, props);
|
||||
validate(result, propertiesName, (T) propValue, props);
|
||||
} else {
|
||||
result.add("'config." + propertyName + "' is expected to be of type " + type + ", " +
|
||||
result.add("'"+propertiesName+"." + propertyName + "' is expected to be of type " + type + ", " +
|
||||
"but is of type '" + propValue.getClass().getSimpleName() + "'");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract void validate(final ArrayList<String> result, final T propValue, final Map<String, Object> props);
|
||||
protected abstract void validate(final ArrayList<String> result, final String propertiesName, final T propValue, final Map<String, Object> props);
|
||||
|
||||
public void verifyConsistency(final Map.Entry<? extends Enum<?>, ?> typeDef) {
|
||||
if (required == null ) {
|
||||
|
@ -23,15 +23,15 @@ public class IntegerPropertyValidator extends HsPropertyValidator<Integer> {
|
||||
|
||||
|
||||
@Override
|
||||
protected void validate(final ArrayList<String> result, final Integer propValue, final Map<String, Object> props) {
|
||||
protected void validate(final ArrayList<String> result, final String propertiesName, final Integer propValue, final Map<String, Object> props) {
|
||||
if (min != null && propValue < min) {
|
||||
result.add("'config." + propertyName + "' is expected to be >= " + min + " but is " + propValue);
|
||||
result.add("'"+propertiesName+"." + propertyName + "' is expected to be >= " + min + " but is " + propValue);
|
||||
}
|
||||
if (max != null && propValue > max) {
|
||||
result.add("'config." + propertyName + "' is expected to be <= " + max + " but is " + propValue);
|
||||
result.add("'"+propertiesName+"." + propertyName + "' is expected to be <= " + max + " but is " + propValue);
|
||||
}
|
||||
if (step != null && propValue % step != 0) {
|
||||
result.add("'config." + propertyName + "' is expected to be multiple of " + step + " but is " + propValue);
|
||||
result.add("'"+propertiesName+"." + propertyName + "' is expected to be multiple of " + step + " but is " + propValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,9 @@ import java.util.Map;
|
||||
|
||||
public interface Validatable<E, T extends Enum<T>> {
|
||||
|
||||
Map<String, Object> getProperties();
|
||||
|
||||
Enum<T> getType();
|
||||
|
||||
String getPropertiesName();
|
||||
Map<String, Object> getProperties();
|
||||
}
|
||||
|
@ -32,9 +32,9 @@ begin
|
||||
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
||||
insert
|
||||
into hs_booking_item (uuid, debitoruuid, type, caption, validity, resources)
|
||||
values (uuid_generate_v4(), relatedDebitor.uuid, 'MANAGED_SERVER', 'some ManagedServer', daterange('20221001', null, '[]'), '{ "CPU": 2, "SDD": 512, "extra": 42 }'::jsonb),
|
||||
(uuid_generate_v4(), relatedDebitor.uuid, 'CLOUD_SERVER', 'some CloudServer', daterange('20230115', '20240415', '[)'), '{ "CPU": 2, "HDD": 1024, "extra": 42 }'::jsonb),
|
||||
(uuid_generate_v4(), relatedDebitor.uuid, 'PRIVATE_CLOUD', 'some PrivateCloud', daterange('20240401', null, '[]'), '{ "CPU": 10, "SDD": 10240, "HDD": 10240, "extra": 42 }'::jsonb);
|
||||
values (uuid_generate_v4(), relatedDebitor.uuid, 'MANAGED_SERVER', 'some ManagedServer', daterange('20221001', null, '[]'), '{ "CPUs": 2, "RAM": 8, "SDD": 512, "Traffic": 42 }'::jsonb),
|
||||
(uuid_generate_v4(), relatedDebitor.uuid, 'CLOUD_SERVER', 'some CloudServer', daterange('20230115', '20240415', '[)'), '{ "CPUs": 2, "RAM": 4, "HDD": 1024, "Traffic": 42 }'::jsonb),
|
||||
(uuid_generate_v4(), relatedDebitor.uuid, 'PRIVATE_CLOUD', 'some PrivateCloud', daterange('20240401', null, '[]'), '{ "CPUs": 10, "SDD": 10240, "HDD": 10240, "Traffic": 42 }'::jsonb);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
@ -44,10 +44,10 @@ begin
|
||||
raise notice 'creating test hosting-asset: %', givenPartnerNumber::text || givenDebitorSuffix::text;
|
||||
raise notice '- using debitor (%): %', relatedDebitor.uuid, relatedDebitor;
|
||||
insert into hs_hosting_asset
|
||||
(uuid, bookingitemuuid, type, parentAssetUuid, identifier, caption, config)
|
||||
(uuid, bookingitemuuid, type, parentAssetUuid, identifier, caption, config)
|
||||
values (managedServerUuid, relatedPrivateCloudBookingItem.uuid, 'MANAGED_SERVER', null, 'vm10' || givenDebitorSuffix, 'some ManagedServer', '{ "CPU": 2, "SDD": 512, "extra": 42 }'::jsonb),
|
||||
(uuid_generate_v4(), relatedPrivateCloudBookingItem.uuid, 'CLOUD_SERVER', null, 'vm20' || givenDebitorSuffix, 'another CloudServer', '{ "CPU": 2, "HDD": 1024, "extra": 42 }'::jsonb),
|
||||
(uuid_generate_v4(), relatedManagedServerBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, givenWebspacePrefix || '01', 'some Webspace', '{ "RAM": 1, "SDD": 512, "HDD": 2048, "extra": 42 }'::jsonb);
|
||||
(uuid_generate_v4(), relatedPrivateCloudBookingItem.uuid, 'CLOUD_SERVER', null, 'vm20' || givenDebitorSuffix, 'another CloudServer', '{ "CPU": 2, "HDD": 1024, "extra": 42 }'::jsonb),
|
||||
(uuid_generate_v4(), relatedManagedServerBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, givenWebspacePrefix || '01', 'some Webspace', '{ "RAM": 1, "SDD": 512, "HDD": 2048, "extra": 42 }'::jsonb);
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
@ -21,6 +21,7 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.matchesRegex;
|
||||
@ -69,37 +70,42 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.body("", lenientlyEquals("""
|
||||
[
|
||||
{
|
||||
"caption": "some ManagedServer",
|
||||
"validFrom": "2022-10-01",
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"CPU": 2,
|
||||
"SDD": 512,
|
||||
"extra": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "some CloudServer",
|
||||
"validFrom": "2023-01-15",
|
||||
"validTo": "2024-04-14",
|
||||
"resources": {
|
||||
"CPU": 2,
|
||||
"HDD": 1024,
|
||||
"extra": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"caption": "some PrivateCloud",
|
||||
"validFrom": "2024-04-01",
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"CPU": 10,
|
||||
"HDD": 10240,
|
||||
"SDD": 10240,
|
||||
"extra": 42
|
||||
}
|
||||
}
|
||||
]
|
||||
"type": "MANAGED_SERVER",
|
||||
"caption": "some ManagedServer",
|
||||
"validFrom": "2022-10-01",
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"RAM": 8,
|
||||
"SDD": 512,
|
||||
"CPUs": 2,
|
||||
"Traffic": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "CLOUD_SERVER",
|
||||
"caption": "some CloudServer",
|
||||
"validFrom": "2023-01-15",
|
||||
"validTo": "2024-04-14",
|
||||
"resources": {
|
||||
"HDD": 1024,
|
||||
"RAM": 4,
|
||||
"CPUs": 2,
|
||||
"Traffic": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "PRIVATE_CLOUD",
|
||||
"caption": "some PrivateCloud",
|
||||
"validFrom": "2024-04-01",
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"HDD": 10240,
|
||||
"SDD": 10240,
|
||||
"CPUs": 10,
|
||||
"Traffic": 42
|
||||
}
|
||||
}
|
||||
]
|
||||
"""));
|
||||
// @formatter:on
|
||||
}
|
||||
@ -123,7 +129,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"debitorUuid": "%s",
|
||||
"type": "MANAGED_SERVER",
|
||||
"caption": "some new booking",
|
||||
"resources": { "CPU": 12, "extra": 42 },
|
||||
"resources": { "CPUs": 12, "RAM": 4, "SSD": 100, "Traffic": 250 },
|
||||
"validFrom": "2022-10-13"
|
||||
}
|
||||
""".formatted(givenDebitor.getUuid()))
|
||||
@ -139,7 +145,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"caption": "some new booking",
|
||||
"validFrom": "2022-10-13",
|
||||
"validTo": null,
|
||||
"resources": { "CPU": 12 }
|
||||
"resources": { "CPUs": 12, "SSD": 100, "Traffic": 250 }
|
||||
}
|
||||
"""))
|
||||
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/booking/items/[^/]*"))
|
||||
@ -177,7 +183,12 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"caption": "some CloudServer",
|
||||
"validFrom": "2023-01-15",
|
||||
"validTo": "2024-04-14",
|
||||
"resources": { CPU: 2, HDD: 1024 }
|
||||
"resources": {
|
||||
"HDD": 1024,
|
||||
"RAM": 4,
|
||||
"CPUs": 2,
|
||||
"Traffic": 42
|
||||
}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
}
|
||||
@ -222,7 +233,12 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"caption": "some CloudServer",
|
||||
"validFrom": "2023-01-15",
|
||||
"validTo": "2024-04-14",
|
||||
"resources": { CPU: 2, HDD: 1024 }
|
||||
"resources": {
|
||||
"HDD": 1024,
|
||||
"RAM": 4,
|
||||
"CPUs": 2,
|
||||
"Traffic": 42
|
||||
}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
}
|
||||
@ -234,7 +250,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
@Test
|
||||
void globalAdmin_canPatchAllUpdatablePropertiesOfBookingItem() {
|
||||
|
||||
final var givenBookingItem = givenSomeTemporaryBookingItemForDebitorNumber(1000111, entry("something", 1));
|
||||
final var givenBookingItem = givenSomeBookingItem(1000111, MANAGED_WEBSPACE,
|
||||
resource("HDD", 100), resource("SSD", 50), resource("Traffic", 250));
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -245,9 +262,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"validFrom": "2020-06-05",
|
||||
"validTo": "2022-12-31",
|
||||
"resources": {
|
||||
"CPU": "4",
|
||||
"Traffic": 500,
|
||||
"HDD": null,
|
||||
"SSD": "4096"
|
||||
"SSD": 100
|
||||
}
|
||||
}
|
||||
""")
|
||||
@ -263,9 +280,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"validFrom": "2022-11-01",
|
||||
"validTo": "2022-12-31",
|
||||
"resources": {
|
||||
"CPU": "4",
|
||||
"SSD": "4096",
|
||||
"something": 1
|
||||
"Traffic": 500,
|
||||
"SSD": 100
|
||||
}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
@ -288,7 +304,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
@Test
|
||||
void globalAdmin_canDeleteArbitraryBookingItem() {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItem = givenSomeTemporaryBookingItemForDebitorNumber(1000111, entry("something", 1));
|
||||
final var givenBookingItem = givenSomeBookingItem(1000111, MANAGED_WEBSPACE,
|
||||
resource("HDD", 100), resource("SSD", 50), resource("Traffic", 250));
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -306,7 +323,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
@Test
|
||||
void normalUser_canNotDeleteUnrelatedBookingItem() {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItem = givenSomeTemporaryBookingItemForDebitorNumber(1000111, entry("something", 1));
|
||||
final var givenBookingItem = givenSomeBookingItem(1000111, MANAGED_WEBSPACE,
|
||||
resource("HDD", 100), resource("SSD", 50), resource("Traffic", 250));
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -322,15 +340,16 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
}
|
||||
}
|
||||
|
||||
private HsBookingItemEntity givenSomeTemporaryBookingItemForDebitorNumber(final int debitorNumber,
|
||||
final Map.Entry<String, Integer> resources) {
|
||||
@SafeVarargs
|
||||
private HsBookingItemEntity givenSomeBookingItem(final int debitorNumber,
|
||||
final HsBookingItemType hsBookingItemType, final Map.Entry<String, Object>... resources) {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).get(0);
|
||||
final var newBookingItem = HsBookingItemEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.debitor(givenDebitor)
|
||||
.type(HsBookingItemType.MANAGED_WEBSPACE)
|
||||
.type(hsBookingItemType)
|
||||
.caption("some test-booking")
|
||||
.resources(Map.ofEntries(resources))
|
||||
.validity(Range.closedOpen(
|
||||
@ -340,4 +359,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
return bookingItemRepo.save(newBookingItem);
|
||||
}).assertSuccessful().returnedValue();
|
||||
}
|
||||
|
||||
private Map.Entry<String, Object> resource(final String key, final Object value) {
|
||||
return entry(key, value);
|
||||
}
|
||||
}
|
||||
|
@ -167,9 +167,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then
|
||||
allTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"HsBookingItemEntity(D-1000212, MANAGED_SERVER, [2022-10-01,), some ManagedServer, { CPU: 2, SDD: 512, extra: 42 })",
|
||||
"HsBookingItemEntity(D-1000212, CLOUD_SERVER, [2023-01-15,2024-04-15), some CloudServer, { CPU: 2, HDD: 1024, extra: 42 })",
|
||||
"HsBookingItemEntity(D-1000212, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPU: 10, HDD: 10240, SDD: 10240, extra: 42 })");
|
||||
"HsBookingItemEntity(D-1000212, MANAGED_SERVER, [2022-10-01,), some ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-1000212, CLOUD_SERVER, [2023-01-15,2024-04-15), some CloudServer, { CPUs: 2, HDD: 1024, RAM: 4, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-1000212, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -184,9 +184,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then:
|
||||
exactlyTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"HsBookingItemEntity(D-1000111, MANAGED_SERVER, [2022-10-01,), some ManagedServer, { CPU: 2, SDD: 512, extra: 42 })",
|
||||
"HsBookingItemEntity(D-1000111, CLOUD_SERVER, [2023-01-15,2024-04-15), some CloudServer, { CPU: 2, HDD: 1024, extra: 42 })",
|
||||
"HsBookingItemEntity(D-1000111, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPU: 10, HDD: 10240, SDD: 10240, extra: 42 })");
|
||||
"HsBookingItemEntity(D-1000111, MANAGED_SERVER, [2022-10-01,), some ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-1000111, CLOUD_SERVER, [2023-01-15,2024-04-15), some CloudServer, { CPUs: 2, HDD: 1024, RAM: 4, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-1000111, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedServerBookingItemValidatorUnitTest {
|
||||
|
||||
@Test
|
||||
void validatesDependentProperties() {
|
||||
// given
|
||||
final var validator = HsBookingItemEntityValidators.forType(MANAGED_SERVER);
|
||||
final var mangedWebspaceBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(Map.ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 25),
|
||||
entry("SSD", 25),
|
||||
entry("Traffic", 250),
|
||||
entry("SLA-EMail", true)
|
||||
))
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'resources.SLA-EMail' is expected to be false because resources.SLA-Platform=BASIC but is true");
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ 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;
|
||||
@ -271,7 +272,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"statusPhrase": "Bad Request",
|
||||
"message": "['config.extra' is not expected but is '42', 'config.CPUs' is expected to be >= 1 but is 0, 'config.RAM' is required but missing, 'config.SSD' is required but missing, 'config.Traffic' is required but missing]"
|
||||
"message": "['config.extra' is not expected but is set to '42', 'config.CPUs' is expected to be >= 1 but is 0, 'config.RAM' is required but missing, 'config.SSD' is required but missing, 'config.Traffic' is required but missing]"
|
||||
}
|
||||
""")); // @formatter:on
|
||||
}
|
||||
@ -364,7 +365,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
@Test
|
||||
void globalAdmin_canPatchAllUpdatablePropertiesOfAsset() {
|
||||
|
||||
final var givenAsset = givenSomeTemporaryAssetForDebitorNumber("2001", entry("something", 1));
|
||||
final var givenAsset = givenSomeTemporaryHostingAsset("2001", CLOUD_SERVER,
|
||||
config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000));
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -373,9 +375,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.body("""
|
||||
{
|
||||
"config": {
|
||||
"CPU": "4",
|
||||
"CPUs": 2,
|
||||
"HDD": null,
|
||||
"SSD": "4096"
|
||||
"SSD": 250
|
||||
}
|
||||
}
|
||||
""")
|
||||
@ -391,9 +393,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"identifier": "vm2001",
|
||||
"caption": "some test-asset",
|
||||
"config": {
|
||||
"CPU": "4",
|
||||
"SSD": "4096",
|
||||
"something": 1
|
||||
"CPUs": 2,
|
||||
"RAM": 100,
|
||||
"SSD": 250
|
||||
}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
@ -402,7 +404,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
|
||||
.matches(asset -> {
|
||||
assertThat(asset.toString()).isEqualTo("HsHostingAssetEntity(CLOUD_SERVER, vm2001, some test-asset, D-1000111:some CloudServer, { CPU: 4, SSD: 4096, something: 1 })");
|
||||
assertThat(asset.toString()).isEqualTo("HsHostingAssetEntity(CLOUD_SERVER, vm2001, some test-asset, D-1000111:some CloudServer, { CPUs: 2, RAM: 100, SSD: 250, Traffic: 2000 })");
|
||||
return true;
|
||||
});
|
||||
}
|
||||
@ -414,7 +416,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
@Test
|
||||
void globalAdmin_canDeleteArbitraryAsset() {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenAsset = givenSomeTemporaryAssetForDebitorNumber("2002", entry("something", 1));
|
||||
final var givenAsset = givenSomeTemporaryHostingAsset("2002", CLOUD_SERVER,
|
||||
config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000));
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -432,7 +435,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
@Test
|
||||
void normalUser_canNotDeleteUnrelatedAsset() {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenAsset = givenSomeTemporaryAssetForDebitorNumber("2003", entry("something", 1));
|
||||
final var givenAsset = givenSomeTemporaryHostingAsset("2003", CLOUD_SERVER,
|
||||
config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000));
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -461,14 +465,16 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
return givenAsset;
|
||||
}
|
||||
|
||||
private HsHostingAssetEntity givenSomeTemporaryAssetForDebitorNumber(final String identifierSuffix,
|
||||
final Map.Entry<String, Integer> resources) {
|
||||
@SafeVarargs
|
||||
private HsHostingAssetEntity givenSomeTemporaryHostingAsset(final String identifierSuffix,
|
||||
final HsHostingAssetType hostingAssetType,
|
||||
final Map.Entry<String, Object>... resources) {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var newAsset = HsHostingAssetEntity.builder()
|
||||
.uuid(UUID.randomUUID())
|
||||
.bookingItem(givenBookingItem("First", "some CloudServer"))
|
||||
.type(HsHostingAssetType.CLOUD_SERVER)
|
||||
.type(hostingAssetType)
|
||||
.identifier("vm" + identifierSuffix)
|
||||
.caption("some test-asset")
|
||||
.config(Map.ofEntries(resources))
|
||||
@ -477,4 +483,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
return assetRepo.save(newAsset);
|
||||
}).assertSuccessful().returnedValue();
|
||||
}
|
||||
|
||||
private Map.Entry<String, Object> config(final String key, final Object value) {
|
||||
return entry(key, value);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ class HsHostingAssetPropsControllerAcceptanceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void globalAdmin_canListPropertiesOfGivenAssetType() {
|
||||
void anyone_canListPropertiesOfGivenAssetType() {
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
@ -52,101 +52,50 @@ class HsHostingAssetPropsControllerAcceptanceTest {
|
||||
.contentType("application/json")
|
||||
.body("", lenientlyEquals("""
|
||||
[
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "CPUs",
|
||||
"required": true,
|
||||
"unit": null,
|
||||
"min": 1,
|
||||
"max": 32,
|
||||
"step": null
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "RAM",
|
||||
"required": true,
|
||||
"unit": "GB",
|
||||
"min": 1,
|
||||
"max": 128,
|
||||
"step": null
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "SSD",
|
||||
"required": true,
|
||||
"unit": "GB",
|
||||
"min": 25,
|
||||
"max": 1000,
|
||||
"step": 25
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "HDD",
|
||||
"required": false,
|
||||
"unit": "GB",
|
||||
"min": 0,
|
||||
"max": 4000,
|
||||
"step": 250
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "Traffic",
|
||||
"required": true,
|
||||
"unit": "GB",
|
||||
"min": 250,
|
||||
"max": 10000,
|
||||
"step": 250
|
||||
},
|
||||
{
|
||||
"type": "enumeration",
|
||||
"propertyName": "SLA-Platform",
|
||||
"required": false,
|
||||
"values": [
|
||||
"BASIC",
|
||||
"EXT8H",
|
||||
"EXT4H",
|
||||
"EXT2H"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"propertyName": "SLA-EMail",
|
||||
"required": false,
|
||||
"falseIf": {
|
||||
"SLA-Platform": "BASIC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"propertyName": "SLA-Maria",
|
||||
"required": false,
|
||||
"falseIf": {
|
||||
"SLA-Platform": "BASIC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"propertyName": "SLA-PgSQL",
|
||||
"required": false,
|
||||
"falseIf": {
|
||||
"SLA-Platform": "BASIC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"propertyName": "SLA-Office",
|
||||
"required": false,
|
||||
"falseIf": {
|
||||
"SLA-Platform": "BASIC"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "boolean",
|
||||
"propertyName": "SLA-Web",
|
||||
"required": false,
|
||||
"falseIf": {
|
||||
"SLA-Platform": "BASIC"
|
||||
}
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "CPUs",
|
||||
"required": true,
|
||||
"unit": null,
|
||||
"min": 1,
|
||||
"max": 32,
|
||||
"step": null
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "RAM",
|
||||
"required": true,
|
||||
"unit": "GB",
|
||||
"min": 1,
|
||||
"max": 128,
|
||||
"step": null
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "SSD",
|
||||
"required": true,
|
||||
"unit": "GB",
|
||||
"min": 25,
|
||||
"max": 1000,
|
||||
"step": 25
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "HDD",
|
||||
"required": false,
|
||||
"unit": "GB",
|
||||
"min": 0,
|
||||
"max": 4000,
|
||||
"step": 250
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "Traffic",
|
||||
"required": true,
|
||||
"unit": "GB",
|
||||
"min": 250,
|
||||
"max": 10000,
|
||||
"step": 250
|
||||
}
|
||||
]
|
||||
"""));
|
||||
|
@ -8,20 +8,19 @@ import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedServerValidatorUnitTest {
|
||||
class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
|
||||
@Test
|
||||
void validatesDependentProperties() {
|
||||
void validatesProperties() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_SERVER);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.config(Map.ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 25),
|
||||
entry("SSD", 25),
|
||||
entry("Traffic", 250),
|
||||
entry("SLA-EMail", true)
|
||||
entry("RAM", 2000),
|
||||
entry("SSD", 256),
|
||||
entry("Traffic", "250"),
|
||||
entry("SLA-Platform", "xxx")
|
||||
))
|
||||
.build();
|
||||
|
||||
@ -29,6 +28,11 @@ class HsManagedServerValidatorUnitTest {
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'config.SLA-EMail' is expected to be false because config.SLA-Platform=BASIC but is true");
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'config.SLA-Platform' is not expected but is set to 'xxx'",
|
||||
"'config.CPUs' is required but missing",
|
||||
"'config.RAM' is expected to be <= 128 but is 2000",
|
||||
"'config.SSD' is expected to be multiple of 25 but is 256",
|
||||
"'config.Traffic' is expected to be of type class java.lang.Integer, but is of type 'String'");
|
||||
}
|
||||
}
|
@ -12,11 +12,11 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANA
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedWebspaceAssetValidatorUnitTest {
|
||||
class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
|
||||
// just to make sure the class is loaded
|
||||
static {
|
||||
new HsManagedWebspaceAssetValidator();
|
||||
new HsManagedWebspaceHostingAssetValidator();
|
||||
}
|
||||
|
||||
final HsBookingItemEntity managedServerBookingItem = HsBookingItemEntity.builder()
|
||||
@ -97,7 +97,7 @@ class HsManagedWebspaceAssetValidatorUnitTest {
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'config.unknown' is not expected but is 'some value'");
|
||||
assertThat(result).containsExactly("'config.unknown' is not expected but is set to 'some value'");
|
||||
}
|
||||
|
||||
@Test
|
Loading…
Reference in New Issue
Block a user