booking-item-to-related-hosting-asset-just-1-to-1 (#61)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: #61
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig 2024-06-18 13:53:11 +02:00
parent cbadc6e2c7
commit 62867a4cac
4 changed files with 55 additions and 46 deletions

View File

@ -17,6 +17,8 @@ import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Type;
import jakarta.persistence.CascadeType;
@ -30,6 +32,7 @@ import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.persistence.Version;
@ -113,9 +116,8 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject {
@JoinColumn(name="parentitemuuid", referencedColumnName="uuid")
private List<HsBookingItemEntity> subBookingItems;
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true)
@JoinColumn(name="bookingitemuuid", referencedColumnName="uuid")
private List<HsHostingAssetEntity> subHostingAssets;
@OneToOne(mappedBy="bookingItem")
private HsHostingAssetEntity relatedHostingAsset;
@Transient
private PatchableMapWrapper<Object> resourcesWrapper;

View File

@ -7,6 +7,7 @@ import org.apache.commons.lang3.function.TriFunction;
import java.util.List;
import static java.util.Collections.emptyList;
import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_EMAIL_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ADDRESS;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_DATABASE;
@ -38,10 +39,11 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
private static TriFunction<HsBookingItemEntity, IntegerProperty, Integer, List<String>> unixUsers() {
return (final HsBookingItemEntity entity, final IntegerProperty prop, final Integer factor) -> {
final var unixUserCount = entity.getSubHostingAssets().stream()
.flatMap(ha -> ha.getSubHostingAssets().stream())
.filter(ha -> ha.getType() == UNIX_USER)
.count();
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset())
.map(ha -> ha.getSubHostingAssets().stream()
.filter(subAsset -> subAsset.getType() == UNIX_USER)
.count())
.orElse(0L);
final long limitingValue = prop.getValue(entity.getResources());
if (unixUserCount > factor*limitingValue) {
return List.of(prop.propertyName() + "=" + limitingValue + " allows at maximum " + limitingValue*factor + " unix users, but " + unixUserCount + " found");
@ -52,13 +54,14 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
private static TriFunction<HsBookingItemEntity, IntegerProperty, Integer, List<String>> databaseUsers() {
return (final HsBookingItemEntity entity, final IntegerProperty prop, final Integer factor) -> {
final var unixUserCount = entity.getSubHostingAssets().stream()
.flatMap(ha -> ha.getSubHostingAssets().stream())
.filter(bi -> bi.getType() == PGSQL_USER || bi.getType() == MARIADB_USER )
.count();
final var dbUserCount = ofNullable(entity.getRelatedHostingAsset())
.map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType() == PGSQL_USER || bi.getType() == MARIADB_USER )
.count())
.orElse(0L);
final long limitingValue = prop.getValue(entity.getResources());
if (unixUserCount > factor*limitingValue) {
return List.of(prop.propertyName() + "=" + limitingValue + " allows at maximum " + limitingValue*factor + " database users, but " + unixUserCount + " found");
if (dbUserCount > factor*limitingValue) {
return List.of(prop.propertyName() + "=" + limitingValue + " allows at maximum " + limitingValue*factor + " database users, but " + dbUserCount + " found");
}
return emptyList();
};
@ -66,12 +69,13 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
private static TriFunction<HsBookingItemEntity, IntegerProperty, Integer, List<String>> databases() {
return (final HsBookingItemEntity entity, final IntegerProperty prop, final Integer factor) -> {
final var unixUserCount = entity.getSubHostingAssets().stream()
.flatMap(ha -> ha.getSubHostingAssets().stream())
.filter(bi -> bi.getType()==PGSQL_USER || bi.getType()==MARIADB_USER )
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
.filter(ha -> ha.getType()==PGSQL_DATABASE || ha.getType()==MARIADB_DATABASE))
.count();
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset())
.map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType()==PGSQL_USER || bi.getType()==MARIADB_USER )
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
.filter(subAsset -> subAsset.getType()==PGSQL_DATABASE || subAsset.getType()==MARIADB_DATABASE))
.count())
.orElse(0L);
final long limitingValue = prop.getValue(entity.getResources());
if (unixUserCount > factor*limitingValue) {
return List.of(prop.propertyName() + "=" + limitingValue + " allows at maximum " + limitingValue*factor + " databases, but " + unixUserCount + " found");
@ -82,12 +86,13 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
private static TriFunction<HsBookingItemEntity, IntegerProperty, Integer, List<String>> eMailAddresses() {
return (final HsBookingItemEntity entity, final IntegerProperty prop, final Integer factor) -> {
final var unixUserCount = entity.getSubHostingAssets().stream()
.flatMap(ha -> ha.getSubHostingAssets().stream())
.filter(bi -> bi.getType() == DOMAIN_EMAIL_SETUP)
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
.filter(ha -> ha.getType()==EMAIL_ADDRESS))
.count();
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset())
.map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType() == DOMAIN_EMAIL_SETUP)
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
.filter(subAsset -> subAsset.getType()==EMAIL_ADDRESS))
.count())
.orElse(0L);
final long limitingValue = prop.getValue(entity.getResources());
if (unixUserCount > factor*limitingValue) {
return List.of(prop.propertyName() + "=" + limitingValue + " allows at maximum " + limitingValue*factor + " databases, but " + unixUserCount + " found");

View File

@ -177,6 +177,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_WEBSPACE, [2022-10-01,), separate ManagedWebspace, { Daemons: 0, Multi: 1, SSD: 100, Traffic: 50 })",
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SSD: 500, Traffic: 500 })",
"HsBookingItemEntity(D-1000212:D-1000212 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10000, RAM: 32, SSD: 4000, Traffic: 2000 })");
assertThat(result.stream().filter(bi -> bi.getRelatedHostingAsset()!=null).findAny())
.as("at least one relatedProject expected, but none found => fetching relatedProject does not work")
.isNotEmpty();
}
@Test

View File

@ -139,27 +139,26 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 1000),
entry("Multi", 1)
))
.subHostingAssets(of(
HsHostingAssetEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("abc00")
.subHostingAssets(concat(
generate(26, HsHostingAssetType.UNIX_USER, "xyz00-%c%c"),
generateDbUsersWithDatabases(3, HsHostingAssetType.PGSQL_USER,
"xyz00_%c%c",
1, HsHostingAssetType.PGSQL_DATABASE
),
generateDbUsersWithDatabases(3, HsHostingAssetType.MARIADB_USER,
"xyz00_%c%c",
2, HsHostingAssetType.MARIADB_DATABASE
),
generateDomainEmailSetupsWithEMailAddresses(26, HsHostingAssetType.DOMAIN_EMAIL_SETUP,
"%c%c.example.com",
10, HsHostingAssetType.EMAIL_ADDRESS
)
))
.build()
))
.relatedHostingAsset(HsHostingAssetEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("abc00")
.subHostingAssets(concat(
generate(26, HsHostingAssetType.UNIX_USER, "xyz00-%c%c"),
generateDbUsersWithDatabases(3, HsHostingAssetType.PGSQL_USER,
"xyz00_%c%c",
1, HsHostingAssetType.PGSQL_DATABASE
),
generateDbUsersWithDatabases(3, HsHostingAssetType.MARIADB_USER,
"xyz00_%c%c",
2, HsHostingAssetType.MARIADB_DATABASE
),
generateDomainEmailSetupsWithEMailAddresses(26, HsHostingAssetType.DOMAIN_EMAIL_SETUP,
"%c%c.example.com",
10, HsHostingAssetType.EMAIL_ADDRESS
)
))
.build()
)
.build();
// when