Compare commits

..

4 Commits

Author SHA1 Message Date
Michael Hoennig
5f2117b5b5 fix potential class loading deadlock in HsHostingAssetEntityValidator 2024-06-14 06:04:51 +02:00
Michael Hoennig
0b307ffdb7 fix potential class loading deadlock in HsBookingItemEntityValidator 2024-06-14 05:51:49 +02:00
Michael Hoennig
4898a8753b cleanup: remove unnecessary method override 2024-06-14 05:10:24 +02:00
Michael Hoennig
42d484fdc6 use MultiValidationException.throwInvalid in office module as well 2024-06-14 05:07:20 +02:00
20 changed files with 152 additions and 149 deletions

View File

@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingItemsA
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemInsertResource;
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemPatchResource;
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemResource; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingItemResource;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
import net.hostsharing.hsadminng.mapper.KeyValueMap; import net.hostsharing.hsadminng.mapper.KeyValueMap;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -19,7 +20,6 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.validated;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange; import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
@RestController @RestController
@ -62,7 +62,8 @@ public class HsBookingItemController implements HsBookingItemsApi {
final var entityToSave = mapper.map(body, HsBookingItemEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(body, HsBookingItemEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var saved = validated(bookingItemRepo.save(entityToSave)); final HsBookingItemEntity entityToSave1 = bookingItemRepo.save(entityToSave);
final var saved = HsBookingItemEntityValidatorRegistry.validated(entityToSave1);
final var uri = final var uri =
MvcUriComponentsBuilder.fromController(getClass()) MvcUriComponentsBuilder.fromController(getClass())
@ -118,7 +119,7 @@ public class HsBookingItemController implements HsBookingItemsApi {
new HsBookingItemEntityPatcher(current).apply(body); new HsBookingItemEntityPatcher(current).apply(body);
final var saved = bookingItemRepo.save(validated(current)); final var saved = bookingItemRepo.save(HsBookingItemEntityValidatorRegistry.validated(current));
final var mapped = mapper.map(saved, HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER); final var mapped = mapper.map(saved, HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(mapped); return ResponseEntity.ok(mapped);
} }

View File

@ -1,64 +1,20 @@
package net.hostsharing.hsadminng.hs.booking.item.validators; package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator; import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
import net.hostsharing.hsadminng.hs.validation.ValidatableProperty; import net.hostsharing.hsadminng.hs.validation.ValidatableProperty;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
import static java.util.Arrays.stream; import static java.util.Arrays.stream;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import static java.util.Optional.ofNullable; import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingItemEntity> { public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingItemEntity> {
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItemEntity>> validators = new HashMap<>();
static {
register(PRIVATE_CLOUD, new HsPrivateCloudBookingItemValidator());
register(CLOUD_SERVER, new HsCloudServerBookingItemValidator());
register(MANAGED_SERVER, new HsManagedServerBookingItemValidator());
register(MANAGED_WEBSPACE, new HsManagedWebspaceBookingItemValidator());
}
private static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItemEntity> validator) {
stream(validator.propertyValidators).forEach( entry -> {
entry.verifyConsistency(Map.entry(type, validator));
});
validators.put(type, validator);
}
public static HsEntityValidator<HsBookingItemEntity> forType(final Enum<HsBookingItemType> type) {
if ( validators.containsKey(type)) {
return validators.get(type);
}
throw new IllegalArgumentException("no validator found for type " + type);
}
public static Set<Enum<HsBookingItemType>> types() {
return validators.keySet();
}
public static List<String> doValidate(final HsBookingItemEntity bookingItem) {
return HsBookingItemEntityValidator.forType(bookingItem.getType()).validate(bookingItem);
}
public static HsBookingItemEntity validated(final HsBookingItemEntity entityToSave) {
MultiValidationException.throwInvalid(doValidate(entityToSave));
return entityToSave;
}
public HsBookingItemEntityValidator(final ValidatableProperty<?>... properties) { public HsBookingItemEntityValidator(final ValidatableProperty<?>... properties) {
super(properties); super(properties);
} }
@ -72,7 +28,7 @@ public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingIte
} }
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) { private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
return bookingItem != null ? HsBookingItemEntityValidator.doValidate(bookingItem) : emptyList(); return bookingItem != null ? HsBookingItemEntityValidatorRegistry.doValidate(bookingItem) : emptyList();
} }
protected List<String> validateAgainstSubEntities(final HsBookingItemEntity bookingItem) { protected List<String> validateAgainstSubEntities(final HsBookingItemEntity bookingItem) {

View File

@ -0,0 +1,55 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static java.util.Arrays.stream;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
public class HsBookingItemEntityValidatorRegistry {
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItemEntity>> validators = new HashMap<>();
static {
register(PRIVATE_CLOUD, new HsPrivateCloudBookingItemValidator());
register(CLOUD_SERVER, new HsCloudServerBookingItemValidator());
register(MANAGED_SERVER, new HsManagedServerBookingItemValidator());
register(MANAGED_WEBSPACE, new HsManagedWebspaceBookingItemValidator());
}
private static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItemEntity> validator) {
stream(validator.propertyValidators).forEach( entry -> {
entry.verifyConsistency(Map.entry(type, validator));
});
validators.put(type, validator);
}
public static HsEntityValidator<HsBookingItemEntity> forType(final Enum<HsBookingItemType> type) {
if ( validators.containsKey(type)) {
return validators.get(type);
}
throw new IllegalArgumentException("no validator found for type " + type);
}
public static Set<Enum<HsBookingItemType>> types() {
return validators.keySet();
}
public static List<String> doValidate(final HsBookingItemEntity bookingItem) {
return HsBookingItemEntityValidatorRegistry.forType(bookingItem.getType()).validate(bookingItem);
}
public static HsBookingItemEntity validated(final HsBookingItemEntity entityToSave) {
MultiValidationException.throwInvalid(doValidate(entityToSave));
return entityToSave;
}
}

View File

@ -1,8 +1,6 @@
package net.hostsharing.hsadminng.hs.booking.item.validators; package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import java.util.List;
import static net.hostsharing.hsadminng.hs.validation.EnumerationProperty.enumerationProperty; import static net.hostsharing.hsadminng.hs.validation.EnumerationProperty.enumerationProperty;
import static net.hostsharing.hsadminng.hs.validation.IntegerProperty.integerProperty; import static net.hostsharing.hsadminng.hs.validation.IntegerProperty.integerProperty;
@ -19,11 +17,4 @@ class HsCloudServerBookingItemValidator extends HsBookingItemEntityValidator {
enumerationProperty("SLA-Infrastructure").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional() enumerationProperty("SLA-Infrastructure").values("BASIC", "EXT8H", "EXT4H", "EXT2H").optional()
); );
} }
@Override
public List<String> validate(final HsBookingItemEntity cloudServerBookingItem) {
final var selfValidation = super.validate(cloudServerBookingItem);
// FIXME return !selfValidation.isEmpty() ? selfValidation : validateParentEntities(cloudServerBookingItem);
return selfValidation;
}
} }

View File

@ -1,5 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset; package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi; import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
@ -20,8 +21,6 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.validated;
@RestController @RestController
public class HsHostingAssetController implements HsHostingAssetsApi { public class HsHostingAssetController implements HsHostingAssetsApi {
@ -62,7 +61,8 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final var entityToSave = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entityToSave = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var saved = validated(assetRepo.save(entityToSave)); final HsHostingAssetEntity persistentEntity = assetRepo.save(entityToSave);
final var saved = HsHostingAssetEntityValidatorRegistry.validated(persistentEntity);
final var uri = final var uri =
MvcUriComponentsBuilder.fromController(getClass()) MvcUriComponentsBuilder.fromController(getClass())
@ -117,7 +117,8 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
new HsHostingAssetEntityPatcher(current).apply(body); new HsHostingAssetEntityPatcher(current).apply(body);
final var saved = validated(assetRepo.save(current)); final HsHostingAssetEntity persistentEntity = assetRepo.save(current);
final var saved = HsHostingAssetEntityValidatorRegistry.validated(persistentEntity);
final var mapped = mapper.map(saved, HsHostingAssetResource.class); final var mapped = mapper.map(saved, HsHostingAssetResource.class);
return ResponseEntity.ok(mapped); return ResponseEntity.ok(mapped);
} }

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset; package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator; import net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetPropsApi; import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetPropsApi;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource; import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetTypeResource;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -15,7 +15,7 @@ public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
@Override @Override
public ResponseEntity<List<String>> listAssetTypes() { public ResponseEntity<List<String>> listAssetTypes() {
final var resource = HsHostingAssetEntityValidator.types().stream() final var resource = HsHostingAssetEntityValidatorRegistry.types().stream()
.map(Enum::name) .map(Enum::name)
.toList(); .toList();
return ResponseEntity.ok(resource); return ResponseEntity.ok(resource);
@ -25,7 +25,8 @@ public class HsHostingAssetPropsController implements HsHostingAssetPropsApi {
public ResponseEntity<List<Object>> listAssetTypeProps( public ResponseEntity<List<Object>> listAssetTypeProps(
final HsHostingAssetTypeResource assetType) { final HsHostingAssetTypeResource assetType) {
final var propValidators = HsHostingAssetEntityValidator.forType(HsHostingAssetType.of(assetType)); final Enum<HsHostingAssetType> type = HsHostingAssetType.of(assetType);
final var propValidators = HsHostingAssetEntityValidatorRegistry.forType(type);
final List<Map<String, Object>> resource = propValidators.properties(); final List<Map<String, Object>> resource = propValidators.properties();
return ResponseEntity.ok(toListOfObjects(resource)); return ResponseEntity.ok(toListOfObjects(resource));
} }

View File

@ -1,61 +1,20 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators; package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator; import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator; import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
import net.hostsharing.hsadminng.hs.validation.ValidatableProperty; import net.hostsharing.hsadminng.hs.validation.ValidatableProperty;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import static java.util.Arrays.stream; import static java.util.Arrays.stream;
import static java.util.Collections.emptyList; import static java.util.Collections.emptyList;
import static java.util.Optional.ofNullable; import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.*;
public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity> { public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAssetEntity> {
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity>> validators = new HashMap<>();
static {
register(CLOUD_SERVER, new HsHostingAssetEntityValidator());
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
register(UNIX_USER, new HsHostingAssetEntityValidator());
}
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity> validator) {
stream(validator.propertyValidators).forEach( entry -> {
entry.verifyConsistency(Map.entry(type, validator));
});
validators.put(type, validator);
}
public static HsEntityValidator<HsHostingAssetEntity> forType(final Enum<HsHostingAssetType> type) {
if ( validators.containsKey(type)) {
return validators.get(type);
}
throw new IllegalArgumentException("no validator found for type " + type);
}
public static Set<Enum<HsHostingAssetType>> types() {
return validators.keySet();
}
public static List<String> doValidate(final HsHostingAssetEntity hostingAsset) {
return HsHostingAssetEntityValidator.forType(hostingAsset.getType()).validate(hostingAsset);
}
public static HsHostingAssetEntity validated(final HsHostingAssetEntity entityToSave) {
MultiValidationException.throwInvalid(doValidate(entityToSave));
return entityToSave;
}
public HsHostingAssetEntityValidator(final ValidatableProperty<?>... properties) { public HsHostingAssetEntityValidator(final ValidatableProperty<?>... properties) {
super(properties); super(properties);
} }
@ -72,11 +31,13 @@ public class HsHostingAssetEntityValidator extends HsEntityValidator<HsHostingAs
} }
private static List<String> optionallyValidate(final HsHostingAssetEntity assetEntity) { private static List<String> optionallyValidate(final HsHostingAssetEntity assetEntity) {
return assetEntity != null ? forType(assetEntity.getType()).validate(assetEntity) : emptyList(); return assetEntity != null ?
HsHostingAssetEntityValidatorRegistry.forType(assetEntity.getType()).validate(assetEntity) :
emptyList();
} }
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) { private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
return bookingItem != null ? HsBookingItemEntityValidator.doValidate(bookingItem) : emptyList(); return bookingItem != null ? HsBookingItemEntityValidatorRegistry.doValidate(bookingItem) : emptyList();
} }
protected List<String> validateSubEntities(final HsHostingAssetEntity assetEntity) { protected List<String> validateSubEntities(final HsHostingAssetEntity assetEntity) {

View File

@ -0,0 +1,50 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
import java.util.*;
import static java.util.Arrays.stream;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.*;
public class HsHostingAssetEntityValidatorRegistry {
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity>> validators = new HashMap<>();
static {
register(CLOUD_SERVER, new HsHostingAssetEntityValidator());
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
register(UNIX_USER, new HsHostingAssetEntityValidator());
}
private static void register(final Enum<HsHostingAssetType> type, final HsEntityValidator<HsHostingAssetEntity> validator) {
stream(validator.propertyValidators).forEach( entry -> {
entry.verifyConsistency(Map.entry(type, validator));
});
validators.put(type, validator);
}
public static HsEntityValidator<HsHostingAssetEntity> forType(final Enum<HsHostingAssetType> type) {
if ( validators.containsKey(type)) {
return validators.get(type);
}
throw new IllegalArgumentException("no validator found for type " + type);
}
public static Set<Enum<HsHostingAssetType>> types() {
return validators.keySet();
}
public static List<String> doValidate(final HsHostingAssetEntity hostingAsset) {
return HsHostingAssetEntityValidatorRegistry.forType(hostingAsset.getType()).validate(hostingAsset);
}
public static HsHostingAssetEntity validated(final HsHostingAssetEntity entityToSave) {
MultiValidationException.throwInvalid(doValidate(entityToSave));
return entityToSave;
}
}

View File

@ -3,6 +3,7 @@ package net.hostsharing.hsadminng.hs.office.coopassets;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopAssetsApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopAssetsApi;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.*; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.*;
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
@ -13,14 +14,12 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import jakarta.persistence.EntityNotFoundException; import jakarta.persistence.EntityNotFoundException;
import jakarta.validation.ValidationException;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import static java.lang.String.join;
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionTypeResource.*; import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopAssetsTransactionTypeResource.*;
@RestController @RestController
@ -97,9 +96,7 @@ public class HsOfficeCoopAssetsTransactionController implements HsOfficeCoopAsse
validateDebitTransaction(requestBody, violations); validateDebitTransaction(requestBody, violations);
validateCreditTransaction(requestBody, violations); validateCreditTransaction(requestBody, violations);
validateAssetValue(requestBody, violations); validateAssetValue(requestBody, violations);
if (violations.size() > 0) { MultiValidationException.throwInvalid(violations);
throw new ValidationException("[" + join(",\n", violations) + "]"); // FIXME: move the join into an exception subclass
}
} }
private static void validateDebitTransaction( private static void validateDebitTransaction(

View File

@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi; import net.hostsharing.hsadminng.hs.office.generated.api.v1.api.HsOfficeCoopSharesApi;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionInsertResource;
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource; import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionResource;
import net.hostsharing.hsadminng.hs.validation.MultiValidationException;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
@ -14,14 +15,12 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import jakarta.validation.ValidationException;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import static java.lang.String.join;
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.CANCELLATION; import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.CANCELLATION;
import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.SUBSCRIPTION; import static net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeCoopSharesTransactionTypeResource.SUBSCRIPTION;
@ -99,9 +98,7 @@ public class HsOfficeCoopSharesTransactionController implements HsOfficeCoopShar
validateSubscriptionTransaction(requestBody, violations); validateSubscriptionTransaction(requestBody, violations);
validateCancellationTransaction(requestBody, violations); validateCancellationTransaction(requestBody, violations);
validateshareCount(requestBody, violations); validateshareCount(requestBody, violations);
if (violations.size() > 0) { MultiValidationException.throwInvalid(violations);
throw new ValidationException("[" + join(",\n", violations) + "]"); // FIXME: move the join into an exception subclass
}
} }
private static void validateSubscriptionTransaction( private static void validateSubscriptionTransaction(

View File

@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.hs.validation; package net.hostsharing.hsadminng.hs.validation;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator; import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -52,9 +52,9 @@ public abstract class HsEntityValidator<E> {
} }
protected List<String> validateParentEntities(final HsBookingItemEntity bookingItem) { protected List<String> validateParentEntities(final HsBookingItemEntity bookingItem) {
return bookingItem.getParentItem() != null return bookingItem.getParentItem() != null ?
? HsBookingItemEntityValidator.doValidate(bookingItem.getParentItem()) HsBookingItemEntityValidatorRegistry.doValidate(bookingItem.getParentItem()) :
: emptyList(); emptyList();
} }
@SafeVarargs @SafeVarargs

View File

@ -11,7 +11,6 @@ import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVAT
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER; import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_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.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.validated;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable; import static org.assertj.core.api.Assertions.catchThrowable;
@ -34,7 +33,7 @@ class HsBookingItemEntityValidatorUnitTest {
.build(); .build();
// when // when
final var result = catchThrowable( ()-> validated(cloudServerBookingItemEntity) ); final var result = catchThrowable( ()-> HsBookingItemEntityValidatorRegistry.validated(cloudServerBookingItemEntity));
// then // then
assertThat(result).isInstanceOf(ValidationException.class) assertThat(result).isInstanceOf(ValidationException.class)
@ -48,7 +47,7 @@ class HsBookingItemEntityValidatorUnitTest {
@Test @Test
void listsTypes() { void listsTypes() {
// when // when
final var result = HsBookingItemEntityValidator.types(); final var result = HsBookingItemEntityValidatorRegistry.types();
// then // then
assertThat(result).containsExactlyInAnyOrder(PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER, MANAGED_WEBSPACE); assertThat(result).containsExactlyInAnyOrder(PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER, MANAGED_WEBSPACE);

View File

@ -13,7 +13,6 @@ import static java.util.Map.ofEntries;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER; import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_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.HsBookingItemType.PRIVATE_CLOUD;
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.forType;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
class HsCloudServerBookingItemValidatorUnitTest { class HsCloudServerBookingItemValidatorUnitTest {
@ -43,7 +42,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidator.doValidate(cloudServerBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(cloudServerBookingItemEntity);
// then // then
assertThat(result).containsExactly("D-12345:Test-Project:Test-Server.resources.SLA-EMail is not expected but is set to 'true'"); assertThat(result).containsExactly("D-12345:Test-Project:Test-Server.resources.SLA-EMail is not expected but is set to 'true'");
@ -52,7 +51,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
@Test @Test
void containsAllValidations() { void containsAllValidations() {
// when // when
final var validator = forType(CLOUD_SERVER); final var validator = HsBookingItemEntityValidatorRegistry.forType(CLOUD_SERVER);
// then // then
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder( assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
@ -106,7 +105,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity); subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
// when // when
final var result = HsBookingItemEntityValidator.doValidate(subCloudServerBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(subCloudServerBookingItemEntity);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(

View File

@ -21,7 +21,6 @@ import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER; import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE; import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD; import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidator.forType;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
class HsManagedServerBookingItemValidatorUnitTest { class HsManagedServerBookingItemValidatorUnitTest {
@ -51,7 +50,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidator.doValidate(mangedServerBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
// then // then
assertThat(result).containsExactly("D-12345:Test-Project:null.resources.SLA-EMail is expected to be false because SLA-Platform=BASIC but is true"); assertThat(result).containsExactly("D-12345:Test-Project:null.resources.SLA-EMail is expected to be false because SLA-Platform=BASIC but is true");
@ -60,7 +59,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
@Test @Test
void containsAllValidations() { void containsAllValidations() {
// when // when
final var validator = forType(MANAGED_SERVER); final var validator = HsBookingItemEntityValidatorRegistry.forType(MANAGED_SERVER);
// then // then
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder( assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
@ -117,7 +116,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity); subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
// when // when
final var result = HsBookingItemEntityValidator.doValidate(subManagedServerBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(subManagedServerBookingItemEntity);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(
@ -163,7 +162,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidator.doValidate(managedWebspaceBookingItem); final var result = HsBookingItemEntityValidatorRegistry.doValidate(managedWebspaceBookingItem);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(

View File

@ -37,7 +37,7 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidator.doValidate(mangedServerBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(
@ -51,7 +51,7 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
@Test @Test
void containsAllValidations() { void containsAllValidations() {
// when // when
final var validator = HsBookingItemEntityValidator.forType(MANAGED_WEBSPACE); final var validator = HsBookingItemEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
// then // then
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder( assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(

View File

@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static java.util.List.of; import static java.util.List.of;
import static java.util.Map.entry; import static java.util.Map.entry;
import static java.util.Map.ofEntries; import static java.util.Map.ofEntries;
@ -48,7 +47,7 @@ class HsPrivateCloudBookingItemValidatorTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidator.doValidate(privateCloudBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
// then // then
assertThat(result).isEmpty(); assertThat(result).isEmpty();
@ -88,7 +87,7 @@ class HsPrivateCloudBookingItemValidatorTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidator.doValidate(privateCloudBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(

View File

@ -7,7 +7,6 @@ import java.util.Map;
import static java.util.Map.entry; import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.forType;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
class HsCloudServerHostingAssetValidatorUnitTest { class HsCloudServerHostingAssetValidatorUnitTest {
@ -22,7 +21,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
entry("RAM", 2000) entry("RAM", 2000)
)) ))
.build(); .build();
final var validator = forType(cloudServerHostingAssetEntity.getType()); final var validator = HsHostingAssetEntityValidatorRegistry.forType(cloudServerHostingAssetEntity.getType());
// when // when
@ -35,7 +34,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test @Test
void containsAllValidations() { void containsAllValidations() {
// when // when
final var validator = forType(CLOUD_SERVER); final var validator = HsHostingAssetEntityValidatorRegistry.forType(CLOUD_SERVER);
// then // then
assertThat(validator.properties()).map(Map::toString).isEmpty(); assertThat(validator.properties()).map(Map::toString).isEmpty();

View File

@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test;
import jakarta.validation.ValidationException; import jakarta.validation.ValidationException;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.validated;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable; import static org.assertj.core.api.Assertions.catchThrowable;
@ -21,7 +20,7 @@ class HsHostingAssetEntityValidatorUnitTest {
.build(); .build();
// when // when
final var result = catchThrowable( ()-> validated(managedServerHostingAssetEntity) ); final var result = catchThrowable( ()-> HsHostingAssetEntityValidatorRegistry.validated(managedServerHostingAssetEntity));
// then // then
assertThat(result).isInstanceOf(ValidationException.class) assertThat(result).isInstanceOf(ValidationException.class)

View File

@ -7,7 +7,6 @@ import java.util.Map;
import static java.util.Map.entry; import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidator.forType;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
class HsManagedServerHostingAssetValidatorUnitTest { class HsManagedServerHostingAssetValidatorUnitTest {
@ -24,7 +23,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
entry("monit_max_ram_usage", 101) entry("monit_max_ram_usage", 101)
)) ))
.build(); .build();
final var validator = forType(mangedWebspaceHostingAssetEntity.getType()); final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedWebspaceHostingAssetEntity.getType());
// when // when
final var result = validator.validate(mangedWebspaceHostingAssetEntity); final var result = validator.validate(mangedWebspaceHostingAssetEntity);

View File

@ -42,7 +42,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
@Test @Test
void validatesIdentifier() { void validatesIdentifier() {
// given // given
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE); final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.parentAsset(mangedServerAssetEntity) .parentAsset(mangedServerAssetEntity)
@ -59,7 +59,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
@Test @Test
void validatesUnknownProperties() { void validatesUnknownProperties() {
// given // given
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE); final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.parentAsset(mangedServerAssetEntity) .parentAsset(mangedServerAssetEntity)
@ -79,7 +79,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
@Test @Test
void validatesValidEntity() { void validatesValidEntity() {
// given // given
final var validator = HsHostingAssetEntityValidator.forType(MANAGED_WEBSPACE); final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.parentAsset(mangedServerAssetEntity) .parentAsset(mangedServerAssetEntity)