From fc2b437a55255f7a0c3b278b376809d11672d538 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Thu, 6 Jun 2024 13:46:14 +0200 Subject: [PATCH] add assigned-asset, add more hosting-asset test-data and introduce HsBookingDebitor+hs_booking_debitor_rv (#58) Co-authored-by: Michael Hoennig Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/58 Reviewed-by: Marc Sandlus --- .../debitor/HsBookingDebitorEntity.java | 55 ++++++++ .../debitor/HsBookingDebitorRepository.java | 14 +++ .../hs/booking/item/HsBookingItemEntity.java | 6 +- .../booking/item/HsBookingItemRepository.java | 3 +- .../project/HsBookingProjectController.java | 16 ++- .../project/HsBookingProjectEntity.java | 7 +- .../project/HsBookingProjectRepository.java | 2 +- .../hosting/asset/HsHostingAssetEntity.java | 20 ++- .../asset/HsHostingAssetRepository.java | 3 +- .../hs/hosting/asset/HsHostingAssetType.java | 6 +- .../HsCloudServerHostingAssetValidator.java | 20 --- .../HsHostingAssetEntityValidators.java | 2 +- .../HsManagedServerHostingAssetValidator.java | 12 +- ...sManagedWebspaceHostingAssetValidator.java | 6 - .../hs-hosting/hs-hosting-asset-schemas.yaml | 4 +- .../changelog/1-rbac/1058-rbac-generators.sql | 11 +- .../6100-hs-booking-debitor.sql | 17 +++ .../6200-hs-booking-project.sql} | 0 .../6203-hs-booking-project-rbac.md} | 0 .../6203-hs-booking-project-rbac.sql} | 0 .../6208-hs-booking-project-test-data.sql} | 0 .../6200-hs-booking-item.sql | 0 .../6203-hs-booking-item-rbac.md | 0 .../6203-hs-booking-item-rbac.sql | 0 .../6208-hs-booking-item-test-data.sql | 0 .../7010-hs-hosting-asset.sql | 11 +- .../7013-hs-hosting-asset-rbac.md | 24 ++-- .../7013-hs-hosting-asset-rbac.sql | 15 ++- .../7018-hs-hosting-asset-test-data.sql | 18 ++- .../db/changelog/db.changelog-master.yaml | 14 ++- .../debitor/HsBookingDebitorEntityTest.java | 33 +++++ .../booking/debitor/TestHsBookingDebitor.java | 13 ++ ...HsBookingItemControllerAcceptanceTest.java | 39 +++--- .../item/HsBookingItemEntityUnitTest.java | 4 +- ...sBookingItemRepositoryIntegrationTest.java | 5 +- ...ookingProjectControllerAcceptanceTest.java | 27 ++-- ...HsBookingProjectEntityPatcherUnitTest.java | 4 +- .../HsBookingProjectEntityUnitTest.java | 8 +- ...okingProjectRepositoryIntegrationTest.java | 18 +-- .../booking/project/TestHsBookingProject.java | 4 +- ...sHostingAssetControllerAcceptanceTest.java | 118 +++++++----------- .../asset/HsHostingAssetEntityUnitTest.java | 40 +++++- ...ingAssetPropsControllerAcceptanceTest.java | 69 +++++----- ...HostingAssetRepositoryIntegrationTest.java | 28 ++--- ...udServerHostingAssetValidatorUnitTest.java | 19 +-- ...sHostingAssetEntityValidatorsUnitTest.java | 15 ++- ...edServerHostingAssetValidatorUnitTest.java | 16 ++- ...WebspaceHostingAssetValidatorUnitTest.java | 38 +----- ...OfficeDebitorControllerAcceptanceTest.java | 2 +- 49 files changed, 438 insertions(+), 348 deletions(-) create mode 100644 src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java create mode 100644 src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorRepository.java delete mode 100644 src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidator.java create mode 100644 src/main/resources/db/changelog/6-hs-booking/610-booking-debitor/6100-hs-booking-debitor.sql rename src/main/resources/db/changelog/6-hs-booking/{610-booking-project/6100-hs-booking-project.sql => 620-booking-project/6200-hs-booking-project.sql} (100%) rename src/main/resources/db/changelog/6-hs-booking/{610-booking-project/6103-hs-booking-project-rbac.md => 620-booking-project/6203-hs-booking-project-rbac.md} (100%) rename src/main/resources/db/changelog/6-hs-booking/{610-booking-project/6103-hs-booking-project-rbac.sql => 620-booking-project/6203-hs-booking-project-rbac.sql} (100%) rename src/main/resources/db/changelog/6-hs-booking/{610-booking-project/6108-hs-booking-project-test-data.sql => 620-booking-project/6208-hs-booking-project-test-data.sql} (100%) rename src/main/resources/db/changelog/6-hs-booking/{620-booking-item => 630-booking-item}/6200-hs-booking-item.sql (100%) rename src/main/resources/db/changelog/6-hs-booking/{620-booking-item => 630-booking-item}/6203-hs-booking-item-rbac.md (100%) rename src/main/resources/db/changelog/6-hs-booking/{620-booking-item => 630-booking-item}/6203-hs-booking-item-rbac.sql (100%) rename src/main/resources/db/changelog/6-hs-booking/{620-booking-item => 630-booking-item}/6208-hs-booking-item-test-data.sql (100%) create mode 100644 src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntityTest.java create mode 100644 src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/TestHsBookingDebitor.java diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java new file mode 100644 index 00000000..3bc83ee6 --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntity.java @@ -0,0 +1,55 @@ +package net.hostsharing.hsadminng.hs.booking.debitor; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import net.hostsharing.hsadminng.errors.DisplayName; +import net.hostsharing.hsadminng.stringify.Stringify; +import net.hostsharing.hsadminng.stringify.Stringifyable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.util.UUID; + +import static net.hostsharing.hsadminng.stringify.Stringify.stringify; + +// a partial HsOfficeDebitorEntity to reduce the number of SQL queries to load the entity +@Entity +@Table(name = "hs_booking_debitor_rv") +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@DisplayName("BookingDebitor") +public class HsBookingDebitorEntity implements Stringifyable { + + public static final String DEBITOR_NUMBER_TAG = "D-"; + + private static Stringify stringify = + stringify(HsBookingDebitorEntity.class, "booking-debitor") + .withIdProp(HsBookingDebitorEntity::toShortString) + .withProp(HsBookingDebitorEntity::getDefaultPrefix) + .quotedValues(false); + + @Id + private UUID uuid; + + @Column(name = "debitornumber") + private Integer debitorNumber; + + @Column(name = "defaultprefix", columnDefinition = "char(3) not null") + private String defaultPrefix; + + @Override + public String toString() { + return stringify.apply(this); + } + + @Override + public String toShortString() { + return DEBITOR_NUMBER_TAG + debitorNumber; + } +} diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorRepository.java new file mode 100644 index 00000000..f69dd72f --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorRepository.java @@ -0,0 +1,14 @@ +package net.hostsharing.hsadminng.hs.booking.debitor; + +import org.springframework.data.repository.Repository; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface HsBookingDebitorRepository extends Repository { + + Optional findByUuid(UUID id); + + List findByDebitorNumber(int debitorNumber); +} diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java index 4739c638..1c5040e7 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntity.java @@ -160,6 +160,10 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject, Validatab return resources; } + public HsBookingProjectEntity getRelatedProject() { + return project != null ? project : parentItem.getRelatedProject(); + } + public static RbacView rbac() { return rbacViewFor("bookingItem", HsBookingItemEntity.class) .withIdentityView(SQL.projection("caption")) @@ -198,6 +202,6 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject, Validatab } public static void main(String[] args) throws IOException { - rbac().generateWithBaseFileName("6-hs-booking/620-booking-item/6203-hs-booking-item-rbac"); + rbac().generateWithBaseFileName("6-hs-booking/630-booking-item/6303-hs-booking-item-rbac"); } } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepository.java index cda96233..9ee9badc 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepository.java @@ -8,9 +8,10 @@ import java.util.UUID; public interface HsBookingItemRepository extends Repository { - List findAll(); Optional findByUuid(final UUID bookingItemUuid); + List findByCaption(String bookingItemCaption); + List findAllByProjectUuid(final UUID projectItemUuid); HsBookingItemEntity save(HsBookingItemEntity current); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java index 10230d0b..1b614dee 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectController.java @@ -1,6 +1,7 @@ package net.hostsharing.hsadminng.hs.booking.project; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjectsApi; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource; import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource; @@ -12,8 +13,10 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; +import jakarta.persistence.EntityNotFoundException; import java.util.List; import java.util.UUID; +import java.util.function.BiConsumer; @RestController public class HsBookingProjectController implements HsBookingProjectsApi { @@ -27,6 +30,9 @@ public class HsBookingProjectController implements HsBookingProjectsApi { @Autowired private HsBookingProjectRepository bookingProjectRepo; + @Autowired + private HsBookingDebitorRepository debitorRepo; + @Override @Transactional(readOnly = true) public ResponseEntity> listBookingProjectsByDebitorUuid( @@ -50,7 +56,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi { context.define(currentUser, assumedRoles); - final var entityToSave = mapper.map(body, HsBookingProjectEntity.class); + final var entityToSave = mapper.map(body, HsBookingProjectEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var saved = bookingProjectRepo.save(entityToSave); @@ -111,4 +117,12 @@ public class HsBookingProjectController implements HsBookingProjectsApi { final var mapped = mapper.map(saved, HsBookingProjectResource.class); return ResponseEntity.ok(mapped); } + + final BiConsumer RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> { + if (resource.getDebitorUuid() != null) { + entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid()) + .orElseThrow(() -> new EntityNotFoundException("ERROR: [400] debitorUuid %s not found".formatted( + resource.getDebitorUuid())))); + } + }; } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntity.java index aee3242f..b1cf4a41 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntity.java @@ -1,6 +1,7 @@ package net.hostsharing.hsadminng.hs.booking.project; import lombok.*; +import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity; import net.hostsharing.hsadminng.rbac.rbacdef.RbacView; @@ -49,7 +50,7 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject { @ManyToOne(optional = false) @JoinColumn(name = "debitoruuid") - private HsOfficeDebitorEntity debitor; + private HsBookingDebitorEntity debitor; @Column(name = "caption") private String caption; @@ -61,7 +62,7 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject { @Override public String toShortString() { - return ofNullable(debitor).map(HsOfficeDebitorEntity::toShortString).orElse("D-???????") + + return ofNullable(debitor).map(HsBookingDebitorEntity::toShortString).orElse("D-???????") + ":" + caption; } @@ -108,6 +109,6 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject { } public static void main(String[] args) throws IOException { - rbac().generateWithBaseFileName("6-hs-booking/610-booking-project/6103-hs-booking-project-rbac"); + rbac().generateWithBaseFileName("6-hs-booking/620-booking-project/6203-hs-booking-project-rbac"); } } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepository.java index b224dad6..f8a171b4 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepository.java @@ -8,8 +8,8 @@ import java.util.UUID; public interface HsBookingProjectRepository extends Repository { - List findAll(); Optional findByUuid(final UUID bookingProjectUuid); + List findByCaption(final String projectCaption); List findAllByDebitorUuid(final UUID bookingProjectUuid); diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java index 04a812a2..8d573c48 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntity.java @@ -33,9 +33,7 @@ import java.util.HashMap; import java.util.Map; import java.util.UUID; -import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn; -import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE; @@ -65,6 +63,7 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata .withProp(HsHostingAssetEntity::getIdentifier) .withProp(HsHostingAssetEntity::getCaption) .withProp(HsHostingAssetEntity::getParentAsset) + .withProp(HsHostingAssetEntity::getAssignedToAsset) .withProp(HsHostingAssetEntity::getBookingItem) .withProp(HsHostingAssetEntity::getConfig) .quotedValues(false); @@ -84,6 +83,10 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata @JoinColumn(name = "parentassetuuid") private HsHostingAssetEntity parentAsset; + @ManyToOne + @JoinColumn(name = "assignedtoassetuuid") + private HsHostingAssetEntity assignedToAsset; + @Column(name = "type") @Enumerated(EnumType.STRING) private HsHostingAssetType type; @@ -144,12 +147,17 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata NULLABLE) .toRole("bookingItem", AGENT).grantPermission(INSERT) - .importEntityAlias("parentAsset", HsHostingAssetEntity.class, usingCase(MANAGED_SERVER), + .importEntityAlias("parentAsset", HsHostingAssetEntity.class, usingDefaultCase(), dependsOnColumn("parentAssetUuid"), directlyFetchedByDependsOnColumn(), NULLABLE) .toRole("parentAsset", ADMIN).grantPermission(INSERT) + .importEntityAlias("assignedToAsset", HsHostingAssetEntity.class, usingDefaultCase(), + dependsOnColumn("assignedToAssetUuid"), + directlyFetchedByDependsOnColumn(), + NULLABLE) + .createRole(OWNER, (with) -> { with.incomingSuperRole("bookingItem", ADMIN); with.incomingSuperRole("parentAsset", ADMIN); @@ -160,13 +168,15 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata with.incomingSuperRole("parentAsset", AGENT); with.permission(UPDATE); }) - .createSubRole(AGENT) + .createSubRole(AGENT, (with) -> { + with.outgoingSubRole("assignedToAsset", TENANT); + }) .createSubRole(TENANT, (with) -> { with.outgoingSubRole("bookingItem", TENANT); with.outgoingSubRole("parentAsset", TENANT); with.permission(SELECT); }) - .limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentServer", "global"); + .limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentAsset", "assignedToAsset", "global"); } public static void main(String[] args) throws IOException { diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepository.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepository.java index 7de7726b..cefe79f6 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepository.java @@ -10,9 +10,10 @@ import java.util.UUID; public interface HsHostingAssetRepository extends Repository { - List findAll(); Optional findByUuid(final UUID serverUuid); + List findByIdentifier(String assetIdentifier); + @Query(""" SELECT asset FROM HsHostingAssetEntity asset WHERE (:projectUuid IS NULL OR asset.bookingItem.project.uuid = :projectUuid) diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java index f4040046..f02a50f0 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetType.java @@ -6,11 +6,13 @@ public enum HsHostingAssetType { MANAGED_SERVER, // named e.g. vm1234 MANAGED_WEBSPACE(MANAGED_SERVER), // named eg. xyz00 UNIX_USER(MANAGED_WEBSPACE), // named e.g. xyz00-abc - DOMAIN_SETUP(UNIX_USER), // named e.g. example.org + DOMAIN_DNS_SETUP(MANAGED_WEBSPACE), // named e.g. example.org + DOMAIN_HTTP_SETUP(MANAGED_WEBSPACE), // named e.g. example.org + DOMAIN_EMAIL_SETUP(MANAGED_WEBSPACE), // named e.g. example.org // TODO.spec: SECURE_MX EMAIL_ALIAS(MANAGED_WEBSPACE), // named e.g. xyz00-abc - EMAIL_ADDRESS(DOMAIN_SETUP), // named e.g. sample@example.org + EMAIL_ADDRESS(DOMAIN_EMAIL_SETUP), // named e.g. sample@example.org PGSQL_USER(MANAGED_WEBSPACE), // named e.g. xyz00_abc PGSQL_DATABASE(MANAGED_WEBSPACE), // named e.g. xyz00_abc, TODO.spec: or PGSQL_USER? MARIADB_USER(MANAGED_WEBSPACE), // named e.g. xyz00_abc diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidator.java deleted file mode 100644 index 8c43dd43..00000000 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidator.java +++ /dev/null @@ -1,20 +0,0 @@ -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 static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty; - -class HsCloudServerHostingAssetValidator extends HsEntityValidator { - - 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() - ); - } -} diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidators.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidators.java index c4eaef0f..11df9a84 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidators.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidators.java @@ -20,7 +20,7 @@ public class HsHostingAssetEntityValidators { private static final Map, HsEntityValidator> validators = new HashMap<>(); static { - register(CLOUD_SERVER, new HsCloudServerHostingAssetValidator()); + register(CLOUD_SERVER, new HsEntityValidator<>()); register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator()); register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator()); } diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidator.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidator.java index aee10839..35f3b81d 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidator.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidator.java @@ -10,11 +10,13 @@ class HsManagedServerHostingAssetValidator extends HsEntityValidator { 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() - ); } @Override diff --git a/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml b/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml index 7390c3c8..8e9dbe02 100644 --- a/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml +++ b/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml @@ -10,7 +10,9 @@ components: - MANAGED_SERVER - MANAGED_WEBSPACE - UNIX_USER - - DOMAIN_SETUP + - DOMAIN_DNS_SETUP + - DOMAIN_HTTP_SETUP + - DOMAIN_EMAIL_SETUP - EMAIL_ALIAS - EMAIL_ADDRESS - PGSQL_USER diff --git a/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql b/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql index 958d3afe..016b8f89 100644 --- a/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql +++ b/src/main/resources/db/changelog/1-rbac/1058-rbac-generators.sql @@ -118,10 +118,13 @@ begin sql = format($sql$ create or replace function %1$sUuidByIdName(givenIdName varchar) returns uuid - language sql - strict as $f$ - select uuid from %1$s_iv iv where iv.idName = givenIdName; - $f$; + language plpgsql as $f$ + declare + singleMatch uuid; + begin + select uuid into strict singleMatch from %1$s_iv iv where iv.idName = givenIdName; + return singleMatch; + end; $f$; $sql$, targetTable); execute sql; diff --git a/src/main/resources/db/changelog/6-hs-booking/610-booking-debitor/6100-hs-booking-debitor.sql b/src/main/resources/db/changelog/6-hs-booking/610-booking-debitor/6100-hs-booking-debitor.sql new file mode 100644 index 00000000..c9dc8287 --- /dev/null +++ b/src/main/resources/db/changelog/6-hs-booking/610-booking-debitor/6100-hs-booking-debitor.sql @@ -0,0 +1,17 @@ +--liquibase formatted sql + +-- ============================================================================ +--changeset hs-booking-debitor-RESTRICTED-VIEW:1 endDelimiter:--// +-- ---------------------------------------------------------------------------- + +create view hs_booking_debitor_rv as + select debitor.uuid, + debitor.version, + (partner.partnerNumber::varchar || debitor.debitorNumberSuffix)::numeric as debitorNumber, + debitor.defaultPrefix + from hs_office_debitor_rv debitor + -- RBAC for debitor is sufficient, for faster access we are bypassing RBAC for the join tables + join hs_office_relation debitorRel on debitor.debitorReluUid=debitorRel.uuid + join hs_office_relation partnerRel on partnerRel.holderUuid=debitorRel.anchorUuid + join hs_office_partner partner on partner.partnerReluUid=partnerRel.uuid; +--// diff --git a/src/main/resources/db/changelog/6-hs-booking/610-booking-project/6100-hs-booking-project.sql b/src/main/resources/db/changelog/6-hs-booking/620-booking-project/6200-hs-booking-project.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/610-booking-project/6100-hs-booking-project.sql rename to src/main/resources/db/changelog/6-hs-booking/620-booking-project/6200-hs-booking-project.sql diff --git a/src/main/resources/db/changelog/6-hs-booking/610-booking-project/6103-hs-booking-project-rbac.md b/src/main/resources/db/changelog/6-hs-booking/620-booking-project/6203-hs-booking-project-rbac.md similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/610-booking-project/6103-hs-booking-project-rbac.md rename to src/main/resources/db/changelog/6-hs-booking/620-booking-project/6203-hs-booking-project-rbac.md diff --git a/src/main/resources/db/changelog/6-hs-booking/610-booking-project/6103-hs-booking-project-rbac.sql b/src/main/resources/db/changelog/6-hs-booking/620-booking-project/6203-hs-booking-project-rbac.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/610-booking-project/6103-hs-booking-project-rbac.sql rename to src/main/resources/db/changelog/6-hs-booking/620-booking-project/6203-hs-booking-project-rbac.sql diff --git a/src/main/resources/db/changelog/6-hs-booking/610-booking-project/6108-hs-booking-project-test-data.sql b/src/main/resources/db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/610-booking-project/6108-hs-booking-project-test-data.sql rename to src/main/resources/db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql diff --git a/src/main/resources/db/changelog/6-hs-booking/620-booking-item/6200-hs-booking-item.sql b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/620-booking-item/6200-hs-booking-item.sql rename to src/main/resources/db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql diff --git a/src/main/resources/db/changelog/6-hs-booking/620-booking-item/6203-hs-booking-item-rbac.md b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.md similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/620-booking-item/6203-hs-booking-item-rbac.md rename to src/main/resources/db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.md diff --git a/src/main/resources/db/changelog/6-hs-booking/620-booking-item/6203-hs-booking-item-rbac.sql b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/620-booking-item/6203-hs-booking-item-rbac.sql rename to src/main/resources/db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql diff --git a/src/main/resources/db/changelog/6-hs-booking/620-booking-item/6208-hs-booking-item-test-data.sql b/src/main/resources/db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql similarity index 100% rename from src/main/resources/db/changelog/6-hs-booking/620-booking-item/6208-hs-booking-item-test-data.sql rename to src/main/resources/db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql index 755dbbec..c6fedb72 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql @@ -9,7 +9,9 @@ create type HsHostingAssetType as enum ( 'MANAGED_SERVER', 'MANAGED_WEBSPACE', 'UNIX_USER', - 'DOMAIN_SETUP', + 'DOMAIN_DNS_SETUP', + 'DOMAIN_HTTP_SETUP', + 'DOMAIN_EMAIL_SETUP', 'EMAIL_ALIAS', 'EMAIL_ADDRESS', 'PGSQL_USER', @@ -27,6 +29,7 @@ create table if not exists hs_hosting_asset bookingItemUuid uuid null references hs_booking_item(uuid), type HsHostingAssetType not null, parentAssetUuid uuid null references hs_hosting_asset(uuid) initially deferred, + assignedToAssetUuid uuid null references hs_hosting_asset(uuid) initially deferred, identifier varchar(80) not null, caption varchar(80), config jsonb not null, @@ -59,9 +62,11 @@ begin when 'MANAGED_SERVER' then null when 'MANAGED_WEBSPACE' then 'MANAGED_SERVER' when 'UNIX_USER' then 'MANAGED_WEBSPACE' - when 'DOMAIN_SETUP' then 'UNIX_USER' + when 'DOMAIN_DNS_SETUP' then 'MANAGED_WEBSPACE' + when 'DOMAIN_HTTP_SETUP' then 'MANAGED_WEBSPACE' + when 'DOMAIN_EMAIL_SETUP' then 'MANAGED_WEBSPACE' when 'EMAIL_ALIAS' then 'MANAGED_WEBSPACE' - when 'EMAIL_ADDRESS' then 'DOMAIN_SETUP' + when 'EMAIL_ADDRESS' then 'DOMAIN_EMAIL_SETUP' when 'PGSQL_USER' then 'MANAGED_WEBSPACE' when 'PGSQL_DATABASE' then 'MANAGED_WEBSPACE' when 'MARIADB_USER' then 'MANAGED_WEBSPACE' diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.md b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.md index b9a65745..bf7780e1 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.md +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.md @@ -25,40 +25,30 @@ subgraph asset["`**asset**`"] perm:asset:INSERT{{asset:INSERT}} perm:asset:DELETE{{asset:DELETE}} perm:asset:UPDATE{{asset:UPDATE}} - perm:asset:SELECT{{asset:SELECT}} end end -subgraph bookingItem["`**bookingItem**`"] +subgraph assignedToAsset["`**assignedToAsset**`"] direction TB - style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px + style assignedToAsset fill:#99bcdb,stroke:#274d6e,stroke-width:8px - subgraph bookingItem:roles[ ] - style bookingItem:roles fill:#99bcdb,stroke:white + subgraph assignedToAsset:roles[ ] + style assignedToAsset:roles fill:#99bcdb,stroke:white - role:bookingItem:OWNER[[bookingItem:OWNER]] - role:bookingItem:ADMIN[[bookingItem:ADMIN]] - role:bookingItem:AGENT[[bookingItem:AGENT]] - role:bookingItem:TENANT[[bookingItem:TENANT]] + role:assignedToAsset:TENANT[[assignedToAsset:TENANT]] end end %% granting roles to roles -role:bookingItem:OWNER -.-> role:bookingItem:ADMIN -role:bookingItem:ADMIN -.-> role:bookingItem:AGENT -role:bookingItem:AGENT -.-> role:bookingItem:TENANT -role:bookingItem:ADMIN ==> role:asset:OWNER role:asset:OWNER ==> role:asset:ADMIN -role:bookingItem:AGENT ==> role:asset:ADMIN role:asset:ADMIN ==> role:asset:AGENT +role:asset:AGENT ==> role:assignedToAsset:TENANT role:asset:AGENT ==> role:asset:TENANT -role:asset:TENANT ==> role:bookingItem:TENANT +role:assignedToAsset:TENANT ==> role:asset:TENANT %% granting permissions to roles role:global:ADMIN ==> perm:asset:INSERT -role:bookingItem:AGENT ==> perm:asset:INSERT role:asset:OWNER ==> perm:asset:DELETE role:asset:ADMIN ==> perm:asset:UPDATE -role:asset:TENANT ==> perm:asset:SELECT ``` diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql index ae6c51c7..f14430a7 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7013-hs-hosting-asset-rbac.sql @@ -31,6 +31,7 @@ create or replace procedure buildRbacSystemForHsHostingAsset( declare newBookingItem hs_booking_item; + newAssignedToAsset hs_hosting_asset; newParentAsset hs_hosting_asset; begin @@ -38,6 +39,8 @@ begin SELECT * FROM hs_booking_item WHERE uuid = NEW.bookingItemUuid INTO newBookingItem; + SELECT * FROM hs_hosting_asset WHERE uuid = NEW.assignedToAssetUuid INTO newAssignedToAsset; + SELECT * FROM hs_hosting_asset WHERE uuid = NEW.parentAssetUuid INTO newParentAsset; perform createRoleWithGrants( @@ -59,13 +62,15 @@ begin perform createRoleWithGrants( hsHostingAssetAGENT(NEW), - incomingSuperRoles => array[hsHostingAssetADMIN(NEW)] + incomingSuperRoles => array[hsHostingAssetADMIN(NEW)], + outgoingSubRoles => array[hsHostingAssetTENANT(newAssignedToAsset)] ); perform createRoleWithGrants( hsHostingAssetTENANT(NEW), - permissions => array['SELECT'], - incomingSuperRoles => array[hsHostingAssetAGENT(NEW)], + incomingSuperRoles => array[ + hsHostingAssetAGENT(NEW), + hsHostingAssetTENANT(newAssignedToAsset)], outgoingSubRoles => array[ hsBookingItemTENANT(newBookingItem), hsHostingAssetTENANT(newParentAsset)] @@ -197,11 +202,11 @@ create or replace function new_hs_hosting_asset_grants_insert_to_hs_hosting_asse language plpgsql strict as $$ begin - if NEW.type = 'MANAGED_SERVER' then + -- unconditional for all rows in that table call grantPermissionToRole( createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'), hsHostingAssetADMIN(NEW)); - end if; + -- end. return NEW; end; $$; diff --git a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql index 737b691a..964acdec 100644 --- a/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql +++ b/src/main/resources/db/changelog/7-hs-hosting/701-hosting-asset/7018-hs-hosting-asset-test-data.sql @@ -16,7 +16,11 @@ declare relatedDebitor hs_office_debitor; relatedPrivateCloudBookingItem hs_booking_item; relatedManagedServerBookingItem hs_booking_item; + debitorNumberSuffix varchar; + defaultPrefix varchar; managedServerUuid uuid; + managedWebspaceUuid uuid; + webUnixUserUuid uuid; begin currentTask := 'creating hosting-asset test-data ' || givenProjectCaption; call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN'); @@ -45,12 +49,18 @@ begin assert relatedManagedServerBookingItem.uuid is not null, 'relatedManagedServerBookingItem for "' || givenProjectCaption|| '" must not be null'; select uuid_generate_v4() into managedServerUuid; + select uuid_generate_v4() into managedWebspaceUuid; + select uuid_generate_v4() into webUnixUserUuid; + debitorNumberSuffix := relatedDebitor.debitorNumberSuffix; + defaultPrefix := relatedDebitor.defaultPrefix; insert into hs_hosting_asset - (uuid, bookingitemuuid, type, parentAssetUuid, identifier, caption, config) - values (managedServerUuid, relatedPrivateCloudBookingItem.uuid, 'MANAGED_SERVER', null, 'vm10' || relatedDebitor.debitorNumberSuffix, 'some ManagedServer', '{ "CPU": 2, "SDD": 512, "extra": 42 }'::jsonb), - (uuid_generate_v4(), relatedPrivateCloudBookingItem.uuid, 'CLOUD_SERVER', null, 'vm20' || relatedDebitor.debitorNumberSuffix, 'another CloudServer', '{ "CPU": 2, "HDD": 1024, "extra": 42 }'::jsonb), - (uuid_generate_v4(), relatedManagedServerBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, relatedDebitor.defaultPrefix || '01', 'some Webspace', '{ "RAM": 1, "SDD": 512, "HDD": 2048, "extra": 42 }'::jsonb); + (uuid, bookingitemuuid, type, parentAssetUuid, assignedToAssetUuid, identifier, caption, config) + values (managedServerUuid, relatedPrivateCloudBookingItem.uuid, 'MANAGED_SERVER', null, null, 'vm10' || debitorNumberSuffix, 'some ManagedServer', '{ "extra": 42 }'::jsonb), + (uuid_generate_v4(), relatedPrivateCloudBookingItem.uuid, 'CLOUD_SERVER', null, null, 'vm20' || debitorNumberSuffix, 'another CloudServer', '{ "extra": 42 }'::jsonb), + (managedWebspaceUuid, relatedManagedServerBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, null, defaultPrefix || '01', 'some Webspace', '{ "extra": 42 }'::jsonb), + (webUnixUserUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some UnixUser for Website', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024", "extra": 42 }'::jsonb), + (uuid_generate_v4(), null, 'DOMAIN_HTTP_SETUP', managedWebspaceUuid, webUnixUserUuid, defaultPrefix || '.example.org', 'some Domain-HTTP-Setup', '{ "option-htdocsfallback": true, "use-fcgiphpbin": "/usr/lib/cgi-bin/php", "validsubdomainnames": "*", "extra": 42 }'::jsonb); end; $$; --// diff --git a/src/main/resources/db/changelog/db.changelog-master.yaml b/src/main/resources/db/changelog/db.changelog-master.yaml index aebf347d..d6b4942b 100644 --- a/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/src/main/resources/db/changelog/db.changelog-master.yaml @@ -130,17 +130,19 @@ databaseChangeLog: - include: file: db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql - include: - file: db/changelog/6-hs-booking/610-booking-project/6100-hs-booking-project.sql + file: db/changelog/6-hs-booking/610-booking-debitor/6100-hs-booking-debitor.sql - include: - file: db/changelog/6-hs-booking/610-booking-project/6103-hs-booking-project-rbac.sql + file: db/changelog/6-hs-booking/620-booking-project/6200-hs-booking-project.sql - include: - file: db/changelog/6-hs-booking/610-booking-project/6108-hs-booking-project-test-data.sql + file: db/changelog/6-hs-booking/620-booking-project/6203-hs-booking-project-rbac.sql - include: - file: db/changelog/6-hs-booking/620-booking-item/6200-hs-booking-item.sql + file: db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql - include: - file: db/changelog/6-hs-booking/620-booking-item/6203-hs-booking-item-rbac.sql + file: db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql - include: - file: db/changelog/6-hs-booking/620-booking-item/6208-hs-booking-item-test-data.sql + file: db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql + - include: + file: db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql - include: file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql - include: diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntityTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntityTest.java new file mode 100644 index 00000000..4275c56c --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/HsBookingDebitorEntityTest.java @@ -0,0 +1,33 @@ +package net.hostsharing.hsadminng.hs.booking.debitor; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class HsBookingDebitorEntityTest { + + @Test + void toStringContainsDebitorNumberAndDefaultPrefix() { + final var given = HsBookingDebitorEntity.builder() + .debitorNumber(1234567) + .defaultPrefix("som") + .build(); + + final var result = given.toString(); + + assertThat(result).isEqualTo("booking-debitor(D-1234567: som)"); + } + + @Test + void toShortStringContainsDefaultPrefix() { + final var given = HsBookingDebitorEntity.builder() + .debitorNumber(1234567) + .defaultPrefix("som") + .build(); + + final var result = given.toShortString(); + + assertThat(result).isEqualTo("D-1234567"); + } + +} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/TestHsBookingDebitor.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/TestHsBookingDebitor.java new file mode 100644 index 00000000..2dcc6c3b --- /dev/null +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/debitor/TestHsBookingDebitor.java @@ -0,0 +1,13 @@ +package net.hostsharing.hsadminng.hs.booking.debitor; + +import lombok.experimental.UtilityClass; + + +@UtilityClass +public class TestHsBookingDebitor { + + public static final HsBookingDebitorEntity TEST_BOOKING_DEBITOR = HsBookingDebitorEntity.builder() + .debitorNumber(1234500) + .defaultPrefix("abc") + .build(); +} diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java index 7f385824..a0054b4f 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java @@ -6,7 +6,6 @@ import io.restassured.http.ContentType; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository; -import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; @@ -17,8 +16,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; import java.time.LocalDate; import java.util.List; import java.util.Map; @@ -53,9 +50,6 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup @Autowired JpaAttempt jpaAttempt; - @PersistenceContext - EntityManager em; - @Nested class ListBookingItems { @@ -180,10 +174,10 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void globalAdmin_canGetArbitraryBookingItem() { context.define("superuser-alex@hostsharing.net"); - final var givenBookingItemUuid = bookingItemRepo.findAll().stream() - .filter(bi -> belongsToDebitorNumber(bi, 1000111)) - .filter(item -> item.getCaption().equals("some ManagedWebspace")) - .findAny().orElseThrow().getUuid(); + final var givenBookingItemUuid = bookingItemRepo.findByCaption("some ManagedWebspace").stream() + .filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "fir")) + .map(HsBookingItemEntity::getUuid) + .findAny().orElseThrow(); RestAssured // @formatter:off .given() @@ -213,8 +207,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void normalUser_canNotGetUnrelatedBookingItem() { context.define("superuser-alex@hostsharing.net"); - final var givenBookingItemUuid = bookingItemRepo.findAll().stream() - .filter(bi -> belongsToDebitorNumber(bi, 1000212)) + final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedServer").stream() + .filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "sec")) .map(HsBookingItemEntity::getUuid) .findAny().orElseThrow(); @@ -229,16 +223,18 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup } @Test - void debitorAgentUser_canGetRelatedBookingItem() { + // TODO.impl: For unknown reason, this test fails in about 50%, not finding the uuid (404), maybe no SELECT permission? + void projectAdmin_canGetRelatedBookingItem() { context.define("superuser-alex@hostsharing.net"); - final var givenBookingItemUuid = bookingItemRepo.findAll().stream() - .filter(bi -> belongsToDebitorNumber(bi, 1000313)) - .filter(item -> item.getCaption().equals("separate ManagedServer")) - .findAny().orElseThrow().getUuid(); + final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedServer").stream() + .filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "thi")) + .map(HsBookingItemEntity::getUuid) + .findAny().orElseThrow(); RestAssured // @formatter:off .given() - .header("current-user", "person-TuckerJack@example.com") + .header("current-user", "superuser-alex@hostsharing.net") + .header("assumed-roles", "hs_booking_project#D-1000313-D-1000313defaultproject:ADMIN") .port(port) .when() .get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid) @@ -261,12 +257,11 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup """)); // @formatter:on } - private static boolean belongsToDebitorNumber(final HsBookingItemEntity bi, final int i) { + private static boolean belongsToDebitorWithDefaultPrefix(final HsBookingItemEntity bi, final String defaultPrefix) { return ofNullable(bi) .map(HsBookingItemEntity::getProject) .map(HsBookingProjectEntity::getDebitor) - .map(HsOfficeDebitorEntity::getDebitorNumber) - .filter(debitorNumber -> debitorNumber == i) + .map(bd -> bd.getDefaultPrefix().equals(defaultPrefix)) .isPresent(); } } @@ -317,7 +312,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup context.define("superuser-alex@hostsharing.net"); assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get() .matches(mandate -> { - assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)"); + assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)"); assertThat(mandate.getValidFrom()).isEqualTo("2022-11-01"); assertThat(mandate.getValidTo()).isEqualTo("2022-12-31"); return true; diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntityUnitTest.java index f311bd09..1b95dc8a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemEntityUnitTest.java @@ -29,14 +29,14 @@ class HsBookingItemEntityUnitTest { void toStringContainsAllPropertiesAndResourcesSortedByKey() { final var result = givenBookingItem.toString(); - assertThat(result).isEqualTo("HsBookingItemEntity(D-1000100:test project, CLOUD_SERVER, [2020-01-01,2031-01-01), some caption, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })"); + assertThat(result).isEqualTo("HsBookingItemEntity(D-1234500:test project, CLOUD_SERVER, [2020-01-01,2031-01-01), some caption, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })"); } @Test void toShortStringContainsOnlyMemberNumberAndCaption() { final var result = givenBookingItem.toShortString(); - assertThat(result).isEqualTo("D-1000100:test project:some caption"); + assertThat(result).isEqualTo("D-1234500:test project:some caption"); } @Test diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java index f4ac6fee..0d1e22ac 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemRepositoryIntegrationTest.java @@ -174,8 +174,8 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup // then allTheseBookingItemsAreReturned( result, - "HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })", "HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })", + "HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })", "HsBookingItemEntity(D-1000212:D-1000212 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })"); } @@ -326,8 +326,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup private HsBookingItemEntity givenSomeTemporaryBookingItem(final String projectCaption) { return jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); - final var givenProject = projectRepo.findAll().stream() - .filter(p -> p.getCaption().equals(projectCaption)) + final var givenProject = projectRepo.findByCaption(projectCaption).stream() .findAny().orElseThrow(); final var newBookingItem = HsBookingItemEntity.builder() .project(givenProject) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java index 31bd8ba0..9a4c2391 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectControllerAcceptanceTest.java @@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.booking.project; import io.restassured.RestAssured; import io.restassured.http.ContentType; import net.hostsharing.hsadminng.HsadminNgApplication; -import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; +import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import org.junit.jupiter.api.Nested; @@ -15,10 +15,8 @@ import org.springframework.transaction.annotation.Transactional; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; -import java.util.Map; import java.util.UUID; -import static java.util.Map.entry; import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.matchesRegex; @@ -40,7 +38,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean HsBookingProjectRepository projectRepo; @Autowired - HsOfficeDebitorRepository debitorRepo; + HsBookingDebitorRepository debitorRepo; @Autowired JpaAttempt jpaAttempt; @@ -56,7 +54,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean // given context("superuser-alex@hostsharing.net"); - final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(1000111).stream() + final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).stream() .findFirst() .orElseThrow(); @@ -87,7 +85,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean void globalAdmin_canAddBookingProject() { context.define("superuser-alex@hostsharing.net"); - final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(1000111).stream() + final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).stream() .findFirst() .orElseThrow(); @@ -128,8 +126,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean @Test void globalAdmin_canGetArbitraryBookingProject() { context.define("superuser-alex@hostsharing.net"); - final var givenBookingProjectUuid = bookingProjectRepo.findAll().stream() - .filter(project -> project.getDebitor().getDebitorNumber() == 1000111) + final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000111 default project").stream() .findAny().orElseThrow().getUuid(); RestAssured // @formatter:off @@ -151,8 +148,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean @Test void normalUser_canNotGetUnrelatedBookingProject() { context.define("superuser-alex@hostsharing.net"); - final var givenBookingProjectUuid = bookingProjectRepo.findAll().stream() - .filter(project -> project.getDebitor().getDebitorNumber() == 1000212) + final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000212 default project").stream() .map(HsBookingProjectEntity::getUuid) .findAny().orElseThrow(); @@ -169,8 +165,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean @Test void debitorAgentUser_canGetRelatedBookingProject() { context.define("superuser-alex@hostsharing.net"); - final var givenBookingProjectUuid = bookingProjectRepo.findAll().stream() - .filter(project -> project.getDebitor().getDebitorNumber() == 1000313) + final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000313 default project").stream() .findAny().orElseThrow().getUuid(); RestAssured // @formatter:off @@ -223,7 +218,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean context.define("superuser-alex@hostsharing.net"); assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get() .matches(mandate -> { - assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)"); + assertThat(mandate.getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)"); return true; }); } @@ -272,7 +267,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean private HsBookingProjectEntity givenSomeBookingProject(final int debitorNumber, final String caption) { return jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net"); - final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).stream().findAny().orElseThrow(); + final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow(); final var newBookingProject = HsBookingProjectEntity.builder() .uuid(UUID.randomUUID()) .debitor(givenDebitor) @@ -282,8 +277,4 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean return bookingProjectRepo.save(newBookingProject); }).assertSuccessful().returnedValue(); } - - private Map.Entry resource(final String key, final Object value) { - return entry(key, value); - } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityPatcherUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityPatcherUnitTest.java index cb059fe2..37229d26 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityPatcherUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityPatcherUnitTest.java @@ -13,7 +13,7 @@ import jakarta.persistence.EntityManager; import java.util.UUID; import java.util.stream.Stream; -import static net.hostsharing.hsadminng.hs.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR; +import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR; import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -46,7 +46,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase< protected HsBookingProjectEntity newInitialEntity() { final var entity = new HsBookingProjectEntity(); entity.setUuid(INITIAL_BOOKING_PROJECT_UUID); - entity.setDebitor(TEST_DEBITOR); + entity.setDebitor(TEST_BOOKING_DEBITOR); entity.setCaption(INITIAL_CAPTION); return entity; } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityUnitTest.java index dd911a8a..1d53070b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectEntityUnitTest.java @@ -2,12 +2,12 @@ package net.hostsharing.hsadminng.hs.booking.project; import org.junit.jupiter.api.Test; -import static net.hostsharing.hsadminng.hs.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR; +import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR; import static org.assertj.core.api.Assertions.assertThat; class HsBookingProjectEntityUnitTest { final HsBookingProjectEntity givenBookingProject = HsBookingProjectEntity.builder() - .debitor(TEST_DEBITOR) + .debitor(TEST_BOOKING_DEBITOR) .caption("some caption") .build(); @@ -15,13 +15,13 @@ class HsBookingProjectEntityUnitTest { void toStringContainsAllPropertiesAndResourcesSortedByKey() { final var result = givenBookingProject.toString(); - assertThat(result).isEqualTo("HsBookingProjectEntity(D-1000100, some caption)"); + assertThat(result).isEqualTo("HsBookingProjectEntity(D-1234500, some caption)"); } @Test void toShortStringContainsOnlyMemberNumberAndCaption() { final var result = givenBookingProject.toShortString(); - assertThat(result).isEqualTo("D-1000100:some caption"); + assertThat(result).isEqualTo("D-1234500:some caption"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java index edc4649a..70676f84 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/HsBookingProjectRepositoryIntegrationTest.java @@ -1,7 +1,7 @@ package net.hostsharing.hsadminng.hs.booking.project; import net.hostsharing.hsadminng.context.Context; -import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; +import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository; import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; import net.hostsharing.hsadminng.rbac.test.Array; @@ -38,7 +38,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea HsBookingProjectRepository projectRepo; @Autowired - HsOfficeDebitorRepository debitorRepo; + HsBookingDebitorRepository debitorRepo; @Autowired RawRbacRoleRepository rawRoleRepo; @@ -63,7 +63,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea // given context("superuser-alex@hostsharing.net"); final var count = bookingProjectRepo.count(); - final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); + final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0); // when final var result = attempt(em, () -> { @@ -92,7 +92,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea // when attempt(em, () -> { - final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); + final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0); final var newBookingProject = HsBookingProjectEntity.builder() .debitor(givenDebitor) .caption("some new booking project") @@ -148,7 +148,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor() { // given context("superuser-alex@hostsharing.net"); - final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream() + final var debitorUuid = debitorRepo.findByDebitorNumber(1000212).stream() .findAny().orElseThrow().getUuid(); // when @@ -164,7 +164,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea public void normalUser_canViewOnlyRelatedBookingProjects() { // given: context("person-FirbySusan@example.com"); - final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000111).stream() + final var debitorUuid = debitorRepo.findByDebitorNumber(1000111).stream() .findAny().orElseThrow().getUuid(); // when: @@ -298,7 +298,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea private HsBookingProjectEntity givenSomeTemporaryBookingProject(final int debitorNumber) { return jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); - final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).get(0); + final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).get(0); final var newBookingProject = HsBookingProjectEntity.builder() .debitor(givenDebitor) .caption("some temp project") @@ -312,7 +312,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea final List actualResult, final String... bookingProjectNames) { assertThat(actualResult) - .extracting(bookingProjectEntity -> bookingProjectEntity.toString()) + .extracting(HsBookingProjectEntity::toString) .containsExactlyInAnyOrder(bookingProjectNames); } @@ -320,7 +320,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea final List actualResult, final String... bookingProjectNames) { assertThat(actualResult) - .extracting(bookingProjectEntity -> bookingProjectEntity.toString()) + .extracting(HsBookingProjectEntity::toString) .contains(bookingProjectNames); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/TestHsBookingProject.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/TestHsBookingProject.java index e00c6aaf..6190c36b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/project/TestHsBookingProject.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/project/TestHsBookingProject.java @@ -2,14 +2,14 @@ package net.hostsharing.hsadminng.hs.booking.project; import lombok.experimental.UtilityClass; -import static net.hostsharing.hsadminng.hs.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR; +import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR; @UtilityClass public class TestHsBookingProject { public static final HsBookingProjectEntity TEST_PROJECT = HsBookingProjectEntity.builder() - .debitor(TEST_DEBITOR) + .debitor(TEST_BOOKING_DEBITOR) .caption("test project") .build(); } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java index d11e7278..5204a1ec 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetControllerAcceptanceTest.java @@ -5,7 +5,6 @@ import io.restassured.http.ContentType; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository; -import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; @@ -21,7 +20,6 @@ import java.util.Map; import java.util.UUID; import static java.util.Map.entry; -import static java.util.Optional.ofNullable; 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; @@ -61,8 +59,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup // given context("superuser-alex@hostsharing.net"); - final var givenProject = projectRepo.findAll().stream() - .filter(p -> p.getCaption().equals("D-1000111 default project")) + final var givenProject = projectRepo.findByCaption("D-1000111 default project").stream() .findAny().orElseThrow(); RestAssured // @formatter:off @@ -81,9 +78,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "identifier": "sec01", "caption": "some Webspace", "config": { - "HDD": 2048, - "RAM": 1, - "SDD": 512, "extra": 42 } }, @@ -92,9 +86,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "identifier": "fir01", "caption": "some Webspace", "config": { - "HDD": 2048, - "RAM": 1, - "SDD": 512, "extra": 42 } }, @@ -103,9 +94,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "identifier": "thi01", "caption": "some Webspace", "config": { - "HDD": 2048, - "RAM": 1, - "SDD": 512, "extra": 42 } } @@ -136,18 +124,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "identifier": "vm1011", "caption": "some ManagedServer", "config": { - "CPU": 2, - "SDD": 512, - "extra": 42 - } - }, - { - "type": "MANAGED_SERVER", - "identifier": "vm1013", - "caption": "some ManagedServer", - "config": { - "CPU": 2, - "SDD": 512, "extra": 42 } }, @@ -156,8 +132,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "identifier": "vm1012", "caption": "some ManagedServer", "config": { - "CPU": 2, - "SDD": 512, + "extra": 42 + } + }, + { + "type": "MANAGED_SERVER", + "identifier": "vm1013", + "caption": "some ManagedServer", + "config": { "extra": 42 } } @@ -186,7 +168,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "type": "MANAGED_SERVER", "identifier": "vm1400", "caption": "some new ManagedServer", - "config": { "CPUs": 2, "RAM": 100, "SSD": 300, "Traffic": 250 } + "config": { "monit_max_ssd_usage": 80, "monit_max_cpu_usage": 90, "monit_max_ram_usage": 70 } } """.formatted(givenBookingItem.getUuid())) .port(port) @@ -200,7 +182,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "type": "MANAGED_SERVER", "identifier": "vm1400", "caption": "some new ManagedServer", - "config": { "CPUs": 2, "RAM": 100, "SSD": 300, "Traffic": 250 } + "config": { "monit_max_ssd_usage": 80, "monit_max_cpu_usage": 90, "monit_max_ram_usage": 70 } } """)) .header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*")) @@ -216,7 +198,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup void parentAssetAgent_canAddSubAsset() { context.define("superuser-alex@hostsharing.net"); - final var givenParentAsset = givenParentAsset("D-1000111 default project", MANAGED_SERVER); + final var givenParentAsset = givenParentAsset(MANAGED_SERVER, "vm1011"); context.define("person-FirbySusan@example.com"); @@ -231,7 +213,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "type": "MANAGED_WEBSPACE", "identifier": "fir90", "caption": "some new ManagedWebspace in client's ManagedServer", - "config": { "SSD": 100, "Traffic": 250 } + "config": {} } """.formatted(givenParentAsset.getUuid())) .port(port) @@ -245,7 +227,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "type": "MANAGED_WEBSPACE", "identifier": "fir90", "caption": "some new ManagedWebspace in client's ManagedServer", - "config": { "SSD": 100, "Traffic": 250 } + "config": {} } """)) .header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*")) @@ -263,7 +245,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup context.define("superuser-alex@hostsharing.net"); final var givenBookingItem = givenBookingItem("D-1000111 default project", "some PrivateCloud"); - final var location = RestAssured // @formatter:off + RestAssured // @formatter:off .given() .header("current-user", "superuser-alex@hostsharing.net") .contentType(ContentType.JSON) @@ -273,7 +255,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "type": "MANAGED_SERVER", "identifier": "vm1400", "caption": "some new ManagedServer", - "config": { "CPUs": 0, "extra": 42 } + "config": { "monit_max_ssd_usage": 0, "monit_max_cpu_usage": 101, "extra": 42 } } """.formatted(givenBookingItem.getUuid())) .port(port) @@ -285,7 +267,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup .body("", lenientlyEquals(""" { "statusPhrase": "Bad Request", - "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]" + "message": "['config.extra' is not expected but is set to '42', 'config.monit_max_ssd_usage' is expected to be >= 10 but is 0, 'config.monit_max_cpu_usage' is expected to be <= 100 but is 101, 'config.monit_max_ram_usage' is required but missing]" } """)); // @formatter:on } @@ -297,9 +279,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void globalAdmin_canGetArbitraryAsset() { context.define("superuser-alex@hostsharing.net"); - final var givenAssetUuid = assetRepo.findAll().stream() - .filter(bi -> bi.getBookingItem().getProject().getDebitor().getDebitorNumber() == 1000111) - .filter(item -> item.getCaption().equals("some ManagedServer")) + final var givenAssetUuid = assetRepo.findByIdentifier("vm1011").stream() + .filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000111 default project")) .findAny().orElseThrow().getUuid(); RestAssured // @formatter:off @@ -315,8 +296,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup { "caption": "some ManagedServer", "config": { - "CPU": 2, - "SDD": 512, "extra": 42 } } @@ -326,8 +305,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void normalUser_canNotGetUnrelatedAsset() { context.define("superuser-alex@hostsharing.net"); - final var givenAssetUuid = assetRepo.findAll().stream() - .filter(bi -> bi.getBookingItem().getProject().getDebitor().getDebitorNumber() == 1000212) + final var givenAssetUuid = assetRepo.findByIdentifier("vm1012").stream() + .filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000212 default project")) .map(HsHostingAssetEntity::getUuid) .findAny().orElseThrow(); @@ -344,9 +323,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void debitorAgentUser_canGetRelatedAsset() { context.define("superuser-alex@hostsharing.net"); - final var givenAssetUuid = assetRepo.findAll().stream() - .filter(bi -> bi.getBookingItem().getProject().getDebitor().getDebitorNumber() == 1000313) - .filter(bi -> bi.getCaption().equals("some ManagedServer")) + final var givenAssetUuid = assetRepo.findByIdentifier("vm1013").stream() + .filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000313 default project")) .findAny().orElseThrow().getUuid(); RestAssured // @formatter:off @@ -363,8 +341,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup "identifier": "vm1013", "caption": "some ManagedServer", "config": { - "CPU": 2, - "SDD": 512, "extra": 42 } } @@ -378,8 +354,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void globalAdmin_canPatchAllUpdatablePropertiesOfAsset() { - final var givenAsset = givenSomeTemporaryHostingAsset("2001", CLOUD_SERVER, - config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000)); + final var givenAsset = givenSomeTemporaryHostingAsset("2001", MANAGED_SERVER, + config("monit_max_ssd_usage", 80), config("monit_max_hdd_usage", 90), config("monit_max_cpu_usage", 90), config("monit_max_ram_usage", 70)); RestAssured // @formatter:off .given() @@ -388,9 +364,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup .body(""" { "config": { - "CPUs": 2, - "HDD": null, - "SSD": 250 + "monit_max_ssd_usage": 85, + "monit_max_hdd_usage": null, + "monit_min_free_ssd": 5 } } """) @@ -402,13 +378,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup .contentType(ContentType.JSON) .body("", lenientlyEquals(""" { - "type": "CLOUD_SERVER", + "type": "MANAGED_SERVER", "identifier": "vm2001", "caption": "some test-asset", "config": { - "CPUs": 2, - "RAM": 100, - "SSD": 250 + "monit_max_cpu_usage": 90, + "monit_max_ram_usage": 70, + "monit_max_ssd_usage": 85, + "monit_min_free_ssd": 5 } } """)); // @formatter:on @@ -417,7 +394,8 @@ 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:D-1000111 default project:test CloudServer, { CPUs: 2, RAM: 100, SSD: 250, Traffic: 2000 })"); + assertThat(asset.toString()).isEqualTo( + "HsHostingAssetEntity(MANAGED_SERVER, vm2001, some test-asset, D-1000111:D-1000111 default project:some ManagedServer, { monit_max_cpu_usage: 90, monit_max_ram_usage: 70, monit_max_ssd_usage: 85, monit_min_free_ssd: 5 })"); return true; }); } @@ -429,8 +407,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void globalAdmin_canDeleteArbitraryAsset() { context.define("superuser-alex@hostsharing.net"); - final var givenAsset = givenSomeTemporaryHostingAsset("2002", CLOUD_SERVER, - config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000)); + final var givenAsset = givenSomeTemporaryHostingAsset("1002", MANAGED_SERVER, + config("monit_max_ssd_usage", 80), config("monit_max_hdd_usage", 90), config("monit_max_cpu_usage", 90), config("monit_max_ram_usage", 70)); RestAssured // @formatter:off .given() @@ -448,8 +426,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup @Test void normalUser_canNotDeleteUnrelatedAsset() { context.define("superuser-alex@hostsharing.net"); - final var givenAsset = givenSomeTemporaryHostingAsset("2003", CLOUD_SERVER, - config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000)); + final var givenAsset = givenSomeTemporaryHostingAsset("1003", MANAGED_SERVER, + config("monit_max_ssd_usage", 80), config("monit_max_hdd_usage", 90), config("monit_max_cpu_usage", 90), config("monit_max_ram_usage", 70)); RestAssured // @formatter:off .given() @@ -466,22 +444,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup } HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) { - return bookingItemRepo.findAll().stream() - .filter(a -> ofNullable(a) - .filter(bi -> bi.getCaption().equals(bookingItemCaption)) - .isPresent()) + return bookingItemRepo.findByCaption(bookingItemCaption).stream() + .filter(bi -> bi.getRelatedProject().getCaption().contains(projectCaption)) .findAny().orElseThrow(); } - HsHostingAssetEntity givenParentAsset(final String projectCaption, final HsHostingAssetType assetType) { - final var givenAsset = assetRepo.findAll().stream() + HsHostingAssetEntity givenParentAsset(final HsHostingAssetType assetType, final String assetIdentifier) { + final var givenAsset = assetRepo.findByIdentifier(assetIdentifier).stream() .filter(a -> a.getType() == assetType) - .filter(a -> ofNullable(a) - .map(HsHostingAssetEntity::getBookingItem) - .map(HsBookingItemEntity::getProject) - .map(HsBookingProjectEntity::getCaption) - .filter(c -> c.equals(projectCaption)) - .isPresent()) .findAny().orElseThrow(); return givenAsset; } @@ -494,7 +464,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup context.define("superuser-alex@hostsharing.net"); final var newAsset = HsHostingAssetEntity.builder() .uuid(UUID.randomUUID()) - .bookingItem(givenBookingItem("D-1000111 default project", "test CloudServer")) + .bookingItem(givenBookingItem("D-1000111 default project", "some ManagedServer")) .type(hostingAssetType) .identifier("vm" + identifierSuffix) .caption("some test-asset") diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntityUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntityUnitTest.java index d87d14f0..e45bdb5b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntityUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetEntityUnitTest.java @@ -20,7 +20,7 @@ class HsHostingAssetEntityUnitTest { entry("SSD-storage", 512), entry("HDD-storage", 2048))) .build(); - final HsHostingAssetEntity givenServer = HsHostingAssetEntity.builder() + final HsHostingAssetEntity givenWebspace = HsHostingAssetEntity.builder() .bookingItem(TEST_BOOKING_ITEM) .type(HsHostingAssetType.MANAGED_WEBSPACE) .parentAsset(givenParentAsset) @@ -31,19 +31,47 @@ class HsHostingAssetEntityUnitTest { entry("SSD-storage", 512), entry("HDD-storage", 2048))) .build(); + final HsHostingAssetEntity givenUnixUser = HsHostingAssetEntity.builder() + .type(HsHostingAssetType.UNIX_USER) + .parentAsset(givenWebspace) + .identifier("xyz00-web") + .caption("some unix-user") + .config(Map.ofEntries( + entry("SSD-soft-quota", 128), + entry("SSD-hard-quota", 256), + entry("HDD-soft-quota", 256), + entry("HDD-hard-quota", 512))) + .build(); + final HsHostingAssetEntity givenDomainHttpSetup = HsHostingAssetEntity.builder() + .type(HsHostingAssetType.DOMAIN_HTTP_SETUP) + .parentAsset(givenWebspace) + .identifier("example.org") + .assignedToAsset(givenUnixUser) + .caption("some domain setup") + .config(Map.ofEntries( + entry("option-htdocsfallback", true), + entry("use-fcgiphpbin", "/usr/lib/cgi-bin/php"), + entry("validsubdomainnames", "*"))) + .build(); @Test void toStringContainsAllPropertiesAndResourcesSortedByKey() { - final var result = givenServer.toString(); - assertThat(result).isEqualTo( - "HsHostingAssetEntity(MANAGED_WEBSPACE, xyz00, some managed webspace, MANAGED_SERVER:vm1234, D-1000100:test project:test booking item, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })"); + assertThat(givenWebspace.toString()).isEqualTo( + "HsHostingAssetEntity(MANAGED_WEBSPACE, xyz00, some managed webspace, MANAGED_SERVER:vm1234, D-1234500:test project:test booking item, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })"); + + assertThat(givenUnixUser.toString()).isEqualTo( + "HsHostingAssetEntity(UNIX_USER, xyz00-web, some unix-user, MANAGED_WEBSPACE:xyz00, { HDD-hard-quota: 512, HDD-soft-quota: 256, SSD-hard-quota: 256, SSD-soft-quota: 128 })"); + + assertThat(givenDomainHttpSetup.toString()).isEqualTo( + "HsHostingAssetEntity(DOMAIN_HTTP_SETUP, example.org, some domain setup, MANAGED_WEBSPACE:xyz00, UNIX_USER:xyz00-web, { option-htdocsfallback: true, use-fcgiphpbin: /usr/lib/cgi-bin/php, validsubdomainnames: * })"); } @Test void toShortStringContainsOnlyMemberNumberAndCaption() { - final var result = givenServer.toShortString(); - assertThat(result).isEqualTo("MANAGED_WEBSPACE:xyz00"); + assertThat(givenWebspace.toShortString()).isEqualTo("MANAGED_WEBSPACE:xyz00"); + assertThat(givenUnixUser.toShortString()).isEqualTo("UNIX_USER:xyz00-web"); + assertThat(givenDomainHttpSetup.toShortString()).isEqualTo("DOMAIN_HTTP_SETUP:example.org"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java index e6cc9acd..55c2e29e 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetPropsControllerAcceptanceTest.java @@ -54,48 +54,57 @@ class HsHostingAssetPropsControllerAcceptanceTest { [ { "type": "integer", - "propertyName": "CPUs", - "required": true, + "propertyName": "monit_min_free_ssd", + "required": false, "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 + "step": null }, { "type": "integer", - "propertyName": "HDD", + "propertyName": "monit_min_free_hdd", "required": false, - "unit": "GB", - "min": 0, + "unit": null, + "min": 1, "max": 4000, - "step": 250 + "step": null }, { "type": "integer", - "propertyName": "Traffic", + "propertyName": "monit_max_ssd_usage", "required": true, - "unit": "GB", - "min": 250, - "max": 10000, - "step": 250 + "unit": "%", + "min": 10, + "max": 100, + "step": null + }, + { + "type": "integer", + "propertyName": "monit_max_hdd_usage", + "required": false, + "unit": "%", + "min": 10, + "max": 100, + "step": null + }, + { + "type": "integer", + "propertyName": "monit_max_cpu_usage", + "required": true, + "unit": "%", + "min": 10, + "max": 100, + "step": null + }, + { + "type": "integer", + "propertyName": "monit_max_ram_usage", + "required": true, + "unit": "%", + "min": 10, + "max": 100, + "step": null } ] """)); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java index e5408b4f..f781046a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/HsHostingAssetRepositoryIntegrationTest.java @@ -4,7 +4,6 @@ import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository; -import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository; import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; import net.hostsharing.hsadminng.rbac.test.Array; @@ -48,9 +47,6 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu @Autowired HsBookingProjectRepository projectRepo; - @Autowired - HsOfficeDebitorRepository debitorRepo; - @Autowired RawRbacRoleRepository rawRoleRepo; @@ -143,7 +139,6 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu "{ grant role:hs_hosting_asset#vm9000:AGENT to role:hs_hosting_asset#vm9000:ADMIN by system and assume }", // tenant - "{ grant perm:hs_hosting_asset#vm9000:SELECT to role:hs_hosting_asset#vm9000:TENANT by system and assume }", "{ grant role:hs_booking_item#somePrivateCloud:TENANT to role:hs_hosting_asset#vm9000:TENANT by system and assume }", null)); @@ -169,17 +164,16 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu // then allTheseServersAreReturned( result, - "HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })", - "HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })", - "HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })"); + "HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedServer, { extra: 42 })", + "HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { extra: 42 })", + "HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { extra: 42 })"); } @Test public void normalUser_canViewOnlyRelatedAsset() { // given: context("person-FirbySusan@example.com"); - final var projectUuid = projectRepo.findAll().stream() - .filter(p -> p.getCaption().equals("D-1000111 default project")) + final var projectUuid = projectRepo.findByCaption("D-1000111 default project").stream() .findAny().orElseThrow().getUuid(); // when: @@ -188,9 +182,9 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu // then: exactlyTheseAssetsAreReturned( result, - "HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })", - "HsHostingAssetEntity(MANAGED_SERVER, vm1011, some ManagedServer, D-1000111:D-1000111 default project:some PrivateCloud, { CPU: 2, SDD: 512, extra: 42 })", - "HsHostingAssetEntity(CLOUD_SERVER, vm2011, another CloudServer, D-1000111:D-1000111 default project:some PrivateCloud, { CPU: 2, HDD: 1024, extra: 42 })"); + "HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { extra: 42 })", + "HsHostingAssetEntity(MANAGED_SERVER, vm1011, some ManagedServer, D-1000111:D-1000111 default project:some PrivateCloud, { extra: 42 })", + "HsHostingAssetEntity(CLOUD_SERVER, vm2011, another CloudServer, D-1000111:D-1000111 default project:some PrivateCloud, { extra: 42 })"); } @Test @@ -206,7 +200,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu // then allTheseServersAreReturned( result, - "HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })"); + "HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { extra: 42 })"); } } @@ -373,8 +367,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu } HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) { - final var givenProject = projectRepo.findAll().stream() - .filter(p -> p.getCaption().equals(projectCaption)) + final var givenProject = projectRepo.findByCaption(projectCaption).stream() .findAny().orElseThrow(); return bookingItemRepo.findAllByProjectUuid(givenProject.getUuid()).stream() .filter(i -> i.getCaption().equals(bookingItemCaption)) @@ -382,8 +375,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu } HsHostingAssetEntity givenManagedServer(final String projectCaption, final HsHostingAssetType type) { - final var givenProject = projectRepo.findAll().stream() - .filter(p -> p.getCaption().equals(projectCaption)) + final var givenProject = projectRepo.findByCaption(projectCaption).stream() .findAny().orElseThrow(); return assetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream() .findAny().orElseThrow(); diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidatorUnitTest.java index ee77c565..de679c40 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidatorUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsCloudServerHostingAssetValidatorUnitTest.java @@ -18,10 +18,7 @@ class HsCloudServerHostingAssetValidatorUnitTest { final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder() .type(CLOUD_SERVER) .config(Map.ofEntries( - entry("RAM", 2000), - entry("SSD", 256), - entry("Traffic", "250"), - entry("SLA-Platform", "xxx") + entry("RAM", 2000) )) .build(); final var validator = forType(cloudServerHostingAssetEntity.getType()); @@ -31,12 +28,7 @@ class HsCloudServerHostingAssetValidatorUnitTest { final var result = validator.validate(cloudServerHostingAssetEntity); // then - 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'"); + assertThat(result).containsExactly("'config.RAM' is not expected but is set to '2000'"); } @Test @@ -45,11 +37,6 @@ class HsCloudServerHostingAssetValidatorUnitTest { final var validator = forType(CLOUD_SERVER); // then - assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder( - "{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}"); + assertThat(validator.properties()).map(Map::toString).isEmpty(); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorsUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorsUnitTest.java index 07eb7517..0e07e30c 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorsUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsHostingAssetEntityValidatorsUnitTest.java @@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test; import jakarta.validation.ValidationException; -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.validators.HsHostingAssetEntityValidators.valid; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; @@ -15,19 +15,18 @@ class HsHostingAssetEntityValidatorsUnitTest { @Test void validThrowsException() { // given - final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder() - .type(CLOUD_SERVER) + final var managedServerHostingAssetEntity = HsHostingAssetEntity.builder() + .type(MANAGED_SERVER) .build(); // when - final var result = catchThrowable( ()-> valid(cloudServerHostingAssetEntity) ); + final var result = catchThrowable( ()-> valid(managedServerHostingAssetEntity) ); // then assertThat(result).isInstanceOf(ValidationException.class) .hasMessageContaining( - "'config.CPUs' is required but missing", - "'config.RAM' is required but missing", - "'config.SSD' is required but missing", - "'config.Traffic' is required but missing"); + "'config.monit_max_ssd_usage' is required but missing", + "'config.monit_max_cpu_usage' is required but missing", + "'config.monit_max_ram_usage' is required but missing"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidatorUnitTest.java index a9ee1433..cb9e066b 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidatorUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedServerHostingAssetValidatorUnitTest.java @@ -18,10 +18,9 @@ class HsManagedServerHostingAssetValidatorUnitTest { final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() .type(MANAGED_SERVER) .config(Map.ofEntries( - entry("RAM", 2000), - entry("SSD", 256), - entry("Traffic", "250"), - entry("SLA-Platform", "xxx") + entry("monit_max_hdd_usage", "90"), + entry("monit_max_cpu_usage", 2), + entry("monit_max_ram_usage", 101) )) .build(); final var validator = forType(mangedWebspaceHostingAssetEntity.getType()); @@ -31,10 +30,9 @@ class HsManagedServerHostingAssetValidatorUnitTest { // then 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'"); + "'config.monit_max_ssd_usage' is required but missing", + "'config.monit_max_hdd_usage' is expected to be of type class java.lang.Integer, but is of type 'String'", + "'config.monit_max_cpu_usage' is expected to be >= 10 but is 2", + "'config.monit_max_ram_usage' is expected to be <= 100 but is 101"); } } diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidatorUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidatorUnitTest.java index 53088072..83634501 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidatorUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/validators/HsManagedWebspaceHostingAssetValidatorUnitTest.java @@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test; import java.util.Map; -import static java.util.Collections.emptyMap; 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_WEBSPACE; @@ -36,11 +35,6 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest { .type(MANAGED_WEBSPACE) .parentAsset(mangedServerAssetEntity) .identifier("xyz00") - .config(Map.ofEntries( - entry("HDD", 0), - entry("SSD", 1), - entry("Traffic", 10) - )) .build(); // when @@ -50,28 +44,6 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest { assertThat(result).containsExactly("'identifier' expected to match '^abc[0-9][0-9]$', but is 'xyz00'"); } - - @Test - void validatesMissingProperties() { - // given - final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE); - final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() - .type(MANAGED_WEBSPACE) - .parentAsset(mangedServerAssetEntity) - .identifier("abc00") - .config(emptyMap()) - .build(); - - // when - final var result = validator.validate(mangedWebspaceHostingAssetEntity); - - // then - assertThat(result).containsExactlyInAnyOrder( - "'config.SSD' is required but missing", - "'config.Traffic' is required but missing" - ); - } - @Test void validatesUnknownProperties() { // given @@ -81,9 +53,6 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest { .parentAsset(mangedServerAssetEntity) .identifier("abc00") .config(Map.ofEntries( - entry("HDD", 0), - entry("SSD", 1), - entry("Traffic", 10), entry("unknown", "some value") )) .build(); @@ -96,18 +65,13 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest { } @Test - void validatesValidProperties() { + void validatesValidEntity() { // given final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE); final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() .type(MANAGED_WEBSPACE) .parentAsset(mangedServerAssetEntity) .identifier("abc00") - .config(Map.ofEntries( - entry("HDD", 200), - entry("SSD", 25), - entry("Traffic", 250) - )) .build(); // when diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java index 27f9f2c8..1408a87d 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/debitor/HsOfficeDebitorControllerAcceptanceTest.java @@ -745,7 +745,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net"); final var count = em.createQuery( - "DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumberSuffix >= " + LOWEST_TEMP_DEBITOR_SUFFIX) + "DELETE FROM HsBookingDebitorEntity d WHERE d.debitorNumberSuffix >= " + LOWEST_TEMP_DEBITOR_SUFFIX) .executeUpdate(); System.out.printf("deleted %d entities%n", count); });