hierarchical-validation-baseline (#59)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/59 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
@@ -8,7 +8,10 @@ import com.tngtech.archunit.lang.ArchRule;
|
||||
import com.tngtech.archunit.lang.ConditionEvents;
|
||||
import com.tngtech.archunit.lang.SimpleConditionEvent;
|
||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -51,6 +54,7 @@ public class ArchitectureTest {
|
||||
"..hs.office.person",
|
||||
"..hs.office.relation",
|
||||
"..hs.office.sepamandate",
|
||||
"..hs.booking.debitor",
|
||||
"..hs.booking.project",
|
||||
"..hs.booking.item",
|
||||
"..hs.booking.item.validators",
|
||||
@@ -155,7 +159,8 @@ public class ArchitectureTest {
|
||||
.that().resideInAPackage("..hs.hosting.(*)..")
|
||||
.should().onlyBeAccessed().byClassesThat()
|
||||
.resideInAnyPackage(
|
||||
"..hs.hosting.(*).."
|
||||
"..hs.hosting.(*)..",
|
||||
"..hs.booking.(*).." // TODO.impl: fix this cyclic dependency
|
||||
);
|
||||
|
||||
@ArchTest
|
||||
@@ -295,9 +300,13 @@ public class ArchitectureTest {
|
||||
static final ArchRule everythingShouldBeFreeOfCycles =
|
||||
slices().matching("net.hostsharing.hsadminng.(*)..")
|
||||
.should().beFreeOfCycles()
|
||||
// TODO.refa: would be great if we could get rid of these cyclic dependencies
|
||||
.ignoreDependency(
|
||||
ContextBasedTest.class,
|
||||
net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService.class);
|
||||
RbacGrantsDiagramService.class)
|
||||
.ignoreDependency(
|
||||
HsBookingItemEntity.class,
|
||||
HsHostingAssetEntity.class);
|
||||
|
||||
|
||||
@ArchTest
|
||||
|
@@ -187,7 +187,7 @@ class RestResponseEntityExceptionHandlerUnitTest {
|
||||
final var givenWebRequest = mock(WebRequest.class);
|
||||
|
||||
// when
|
||||
final var errorResponse = exceptionHandler.handleIbanAndBicExceptions(givenException, givenWebRequest);
|
||||
final var errorResponse = exceptionHandler.handleValidationExceptions(givenException, givenWebRequest);
|
||||
|
||||
// then
|
||||
assertThat(errorResponse.getBody().getStatusCode()).isEqualTo(400);
|
||||
|
@@ -4,7 +4,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsBookingDebitorEntityTest {
|
||||
class HsBookingDebitorEntityUnitTest {
|
||||
|
||||
@Test
|
||||
void toStringContainsDebitorNumberAndDefaultPrefix() {
|
@@ -77,14 +77,14 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
[
|
||||
{
|
||||
"type": "MANAGED_WEBSPACE",
|
||||
"caption": "some ManagedWebspace",
|
||||
"caption": "separate ManagedWebspace",
|
||||
"validFrom": "2022-10-01",
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"SDD": 512,
|
||||
"Multi": 4,
|
||||
"Daemons": 2,
|
||||
"Traffic": 12
|
||||
"SSD": 100,
|
||||
"Multi": 1,
|
||||
"Daemons": 0,
|
||||
"Traffic": 50
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -94,9 +94,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"RAM": 8,
|
||||
"SDD": 512,
|
||||
"SSD": 500,
|
||||
"CPUs": 2,
|
||||
"Traffic": 42
|
||||
"Traffic": 500
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -105,10 +105,11 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"validFrom": "2024-04-01",
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"HDD": 10240,
|
||||
"SDD": 10240,
|
||||
"HDD": 10000,
|
||||
"RAM": 32,
|
||||
"SSD": 4000,
|
||||
"CPUs": 10,
|
||||
"Traffic": 42
|
||||
"Traffic": 2000
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -174,7 +175,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
@Test
|
||||
void globalAdmin_canGetArbitraryBookingItem() {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItemUuid = bookingItemRepo.findByCaption("some ManagedWebspace").stream()
|
||||
final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedWebspace").stream()
|
||||
.filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "fir"))
|
||||
.map(HsBookingItemEntity::getUuid)
|
||||
.findAny().orElseThrow();
|
||||
@@ -191,14 +192,14 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"type": "MANAGED_WEBSPACE",
|
||||
"caption": "some ManagedWebspace",
|
||||
"caption": "separate ManagedWebspace",
|
||||
"validFrom": "2022-10-01",
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"SDD": 512,
|
||||
"Multi": 4,
|
||||
"Daemons": 2,
|
||||
"Traffic": 12
|
||||
"SSD": 100,
|
||||
"Multi": 1,
|
||||
"Daemons": 0,
|
||||
"Traffic": 50
|
||||
}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
@@ -227,14 +228,16 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
void projectAdmin_canGetRelatedBookingItem() {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedServer").stream()
|
||||
.filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "thi"))
|
||||
.filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "sec"))
|
||||
.map(HsBookingItemEntity::getUuid)
|
||||
.findAny().orElseThrow();
|
||||
|
||||
generateRbacDiagramForObjectPermission(givenBookingItemUuid, "SELECT", "select");
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-user", "superuser-alex@hostsharing.net")
|
||||
.header("assumed-roles", "hs_booking_project#D-1000313-D-1000313defaultproject:ADMIN")
|
||||
.header("assumed-roles", "hs_booking_project#D-1000212-D-1000212defaultproject:ADMIN")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
||||
@@ -249,9 +252,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"validTo": null,
|
||||
"resources": {
|
||||
"RAM": 8,
|
||||
"SDD": 512,
|
||||
"SSD": 500,
|
||||
"CPUs": 2,
|
||||
"Traffic": 42
|
||||
"Traffic": 500
|
||||
}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
@@ -261,7 +264,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
return ofNullable(bi)
|
||||
.map(HsBookingItemEntity::getProject)
|
||||
.map(HsBookingProjectEntity::getDebitor)
|
||||
.map(bd -> bd.getDefaultPrefix().equals(defaultPrefix))
|
||||
.filter(bd -> bd.getDefaultPrefix().equals(defaultPrefix))
|
||||
.isPresent();
|
||||
}
|
||||
}
|
||||
|
@@ -44,11 +44,11 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
private static final Map<String, Object> PATCH_RESOURCES = patchMap(
|
||||
entry("CPU", 2),
|
||||
entry("HDD", null),
|
||||
entry("SDD", 256)
|
||||
entry("SSD", 256)
|
||||
);
|
||||
private static final Map<String, Object> PATCHED_RESOURCES = patchMap(
|
||||
entry("CPU", 2),
|
||||
entry("SDD", 256),
|
||||
entry("SSD", 256),
|
||||
entry("MEM", 64)
|
||||
);
|
||||
|
||||
|
@@ -6,7 +6,7 @@ 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;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
@@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGE
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||
import static net.hostsharing.hsadminng.rbac.test.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.mapper.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -174,9 +174,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then
|
||||
allTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"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 })");
|
||||
"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 })");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -194,9 +194,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
||||
// then:
|
||||
exactlyTheseBookingItemsAreReturned(
|
||||
result,
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })",
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SSD: 500, Traffic: 500 })",
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, MANAGED_WEBSPACE, [2022-10-01,), separate ManagedWebspace, { Daemons: 0, Multi: 1, SSD: 100, Traffic: 50 })",
|
||||
"HsBookingItemEntity(D-1000111:D-1000111 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10000, RAM: 32, SSD: 4000, Traffic: 2000 })");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,55 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
class HsBookingItemEntityValidatorUnitTest {
|
||||
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
|
||||
.debitorNumber(12345)
|
||||
.build();
|
||||
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
|
||||
.debitor(debitor)
|
||||
.caption("test project")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void validThrowsException() {
|
||||
// given
|
||||
final var cloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.project(project)
|
||||
.caption("Test-Server")
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = catchThrowable( ()-> HsBookingItemEntityValidatorRegistry.validated(cloudServerBookingItemEntity));
|
||||
|
||||
// then
|
||||
assertThat(result).isInstanceOf(ValidationException.class)
|
||||
.hasMessageContaining(
|
||||
"'D-12345:test project:Test-Server.resources.CPUs' is required but missing",
|
||||
"'D-12345:test project:Test-Server.resources.RAM' is required but missing",
|
||||
"'D-12345:test project:Test-Server.resources.SSD' is required but missing",
|
||||
"'D-12345:test project:Test-Server.resources.Traffic' is required but missing");
|
||||
}
|
||||
|
||||
@Test
|
||||
void listsTypes() {
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidatorRegistry.types();
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(PRIVATE_CLOUD, CLOUD_SERVER, MANAGED_SERVER, MANAGED_WEBSPACE);
|
||||
}
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidators.valid;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
|
||||
class HsBookingItemEntityValidatorsUnitTest {
|
||||
|
||||
@Test
|
||||
void validThrowsException() {
|
||||
// given
|
||||
final var cloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = catchThrowable( ()-> valid(cloudServerBookingItemEntity) );
|
||||
|
||||
// then
|
||||
assertThat(result).isInstanceOf(ValidationException.class)
|
||||
.hasMessageContaining(
|
||||
"'resources.CPUs' is required but missing",
|
||||
"'resources.RAM' is required but missing",
|
||||
"'resources.SSD' is required but missing",
|
||||
"'resources.Traffic' is required but missing");
|
||||
}
|
||||
|
||||
@Test
|
||||
void listsTypes() {
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidators.types();
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(CLOUD_SERVER, MANAGED_SERVER, MANAGED_WEBSPACE);
|
||||
}
|
||||
}
|
@@ -1,23 +1,37 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.List.of;
|
||||
import static java.util.Map.entry;
|
||||
import static java.util.Map.ofEntries;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidators.forType;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsCloudServerBookingItemValidatorUnitTest {
|
||||
|
||||
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
|
||||
.debitorNumber(12345)
|
||||
.build();
|
||||
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
|
||||
.debitor(debitor)
|
||||
.caption("Test-Project")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void validatesProperties() {
|
||||
// given
|
||||
final var validator = HsBookingItemEntityValidators.forType(CLOUD_SERVER);
|
||||
final var cloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.project(project)
|
||||
.caption("Test-Server")
|
||||
.resources(Map.ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 25),
|
||||
@@ -28,24 +42,77 @@ class HsCloudServerBookingItemValidatorUnitTest {
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(cloudServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(cloudServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'resources.SLA-EMail' is not expected but is set to 'true'");
|
||||
assertThat(result).containsExactly("'D-12345:Test-Project:Test-Server.resources.SLA-EMail' is not expected but is set to 'true'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = forType(CLOUD_SERVER);
|
||||
final var validator = HsBookingItemEntityValidatorRegistry.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}",
|
||||
"{type=enumeration, propertyName=SLA-Infrastructure, required=false, values=[BASIC, EXT8H, EXT4H, EXT2H]}");
|
||||
"{type=integer, propertyName=CPUs, min=1, max=32, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=RAM, unit=GB, min=1, max=128, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=25, max=1000, step=25, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=4000, step=250, required=false, defaultValue=0, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=250, max=10000, step=250, required=true, isTotalsValidator=false}",
|
||||
"{type=enumeration, propertyName=SLA-Infrastructure, values=[BASIC, EXT8H, EXT4H, EXT2H], required=false, isTotalsValidator=false}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesExceedingPropertyTotals() {
|
||||
// given
|
||||
final var subCloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.caption("Test Cloud-Server")
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build();
|
||||
final HsBookingItemEntity subManagedServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.caption("Test Managed-Server")
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 3),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 3000)
|
||||
))
|
||||
.build();
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(PRIVATE_CLOUD)
|
||||
.project(project)
|
||||
.caption("Test Cloud")
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
subManagedServerBookingItemEntity,
|
||||
subCloudServerBookingItemEntity
|
||||
))
|
||||
.build();
|
||||
subManagedServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(subCloudServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'D-12345:Test-Project:Test Cloud.resources.CPUs' maximum total is 4, but actual total CPUs 5",
|
||||
"'D-12345:Test-Project:Test Cloud.resources.RAM' maximum total is 20 GB, but actual total RAM 30 GB",
|
||||
"'D-12345:Test-Project:Test Cloud.resources.SSD' maximum total is 100 GB, but actual total SSD 150 GB",
|
||||
"'D-12345:Test-Project:Test Cloud.resources.Traffic' maximum total is 5000 GB, but actual total Traffic 5500 GB"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,56 +1,228 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static java.util.List.of;
|
||||
import static java.util.Map.entry;
|
||||
import static java.util.Map.ofEntries;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidators.forType;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedServerBookingItemValidatorUnitTest {
|
||||
|
||||
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
|
||||
.debitorNumber(12345)
|
||||
.build();
|
||||
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
|
||||
.debitor(debitor)
|
||||
.caption("Test-Project")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void validatesProperties() {
|
||||
// given
|
||||
final var validator = HsBookingItemEntityValidators.forType(MANAGED_SERVER);
|
||||
final var mangedServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.project(project)
|
||||
.resources(Map.ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 25),
|
||||
entry("SSD", 25),
|
||||
entry("Traffic", 250),
|
||||
entry("SLA-Platform", "BASIC"),
|
||||
entry("SLA-EMail", true)
|
||||
))
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'resources.SLA-EMail' is expected to be false because resources.SLA-Platform=BASIC but is true");
|
||||
assertThat(result).containsExactly("'D-12345:Test-Project:null.resources.SLA-EMail' is expected to be false because SLA-Platform=BASIC but is true");
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = forType(MANAGED_SERVER);
|
||||
final var validator = HsBookingItemEntityValidatorRegistry.forType(MANAGED_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}",
|
||||
"{type=enumeration, propertyName=SLA-Platform, required=false, values=[BASIC, EXT8H, EXT4H, EXT2H]}",
|
||||
"{type=boolean, propertyName=SLA-EMail, required=false, falseIf={SLA-Platform=BASIC}}",
|
||||
"{type=boolean, propertyName=SLA-Maria, required=false, falseIf={SLA-Platform=BASIC}}",
|
||||
"{type=boolean, propertyName=SLA-PgSQL, required=false, falseIf={SLA-Platform=BASIC}}",
|
||||
"{type=boolean, propertyName=SLA-Office, required=false, falseIf={SLA-Platform=BASIC}}",
|
||||
"{type=boolean, propertyName=SLA-Web, required=false, falseIf={SLA-Platform=BASIC}}");
|
||||
"{type=integer, propertyName=CPUs, min=1, max=32, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=RAM, unit=GB, min=1, max=128, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=25, max=1000, step=25, required=true, isTotalsValidator=true, thresholdPercentage=200}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=4000, step=250, required=false, defaultValue=0, isTotalsValidator=true, thresholdPercentage=200}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=250, max=10000, step=250, required=true, isTotalsValidator=true, thresholdPercentage=200}",
|
||||
"{type=enumeration, propertyName=SLA-Platform, values=[BASIC, EXT8H, EXT4H, EXT2H], required=false, defaultValue=BASIC, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-EMail, required=false, defaultValue=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-Maria, required=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-PgSQL, required=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-Office, required=false, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=SLA-Web, required=false, isTotalsValidator=false}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesExceedingPropertyTotals() {
|
||||
// given
|
||||
final var subCloudServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build();
|
||||
final HsBookingItemEntity subManagedServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 3),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 3000)
|
||||
))
|
||||
.build();
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(PRIVATE_CLOUD)
|
||||
.project(project)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
subManagedServerBookingItemEntity,
|
||||
subCloudServerBookingItemEntity
|
||||
))
|
||||
.build();
|
||||
|
||||
subManagedServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(subManagedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'D-12345:Test-Project:null.resources.CPUs' maximum total is 4, but actual total CPUs 5",
|
||||
"'D-12345:Test-Project:null.resources.RAM' maximum total is 20 GB, but actual total RAM 30 GB",
|
||||
"'D-12345:Test-Project:null.resources.SSD' maximum total is 100 GB, but actual total SSD 150 GB",
|
||||
"'D-12345:Test-Project:null.resources.Traffic' maximum total is 5000 GB, but actual total Traffic 5500 GB"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesExceedingTotals() {
|
||||
// given
|
||||
final var managedWebspaceBookingItem = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.project(project)
|
||||
.caption("test Managed-Webspace")
|
||||
.resources(ofEntries(
|
||||
entry("SSD", 100),
|
||||
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()
|
||||
))
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(managedWebspaceBookingItem);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'D-12345:Test-Project:test Managed-Webspace.resources.Multi=1 allows at maximum 25 unix users, but 26 found",
|
||||
"'D-12345:Test-Project:test Managed-Webspace.resources.Multi=1 allows at maximum 5 database users, but 6 found",
|
||||
"'D-12345:Test-Project:test Managed-Webspace.resources.Multi=1 allows at maximum 5 databases, but 9 found",
|
||||
"'D-12345:Test-Project:test Managed-Webspace.resources.Multi=1 allows at maximum 250 databases, but 260 found"
|
||||
);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
private List<HsHostingAssetEntity> concat(final List<HsHostingAssetEntity>... hostingAssets) {
|
||||
return stream(hostingAssets)
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<HsHostingAssetEntity> generate(final int count, final HsHostingAssetType hostingAssetType,
|
||||
final String identifierPattern) {
|
||||
return IntStream.range(0, count)
|
||||
.mapToObj(number -> HsHostingAssetEntity.builder()
|
||||
.type(hostingAssetType)
|
||||
.identifier(identifierPattern.formatted((number/'a')+'a', (number%'a')+'a'))
|
||||
.build())
|
||||
.toList();
|
||||
}
|
||||
|
||||
private List<HsHostingAssetEntity> generateDbUsersWithDatabases(
|
||||
final int userCount,
|
||||
final HsHostingAssetType directAssetType,
|
||||
final String directAssetIdentifierFormat,
|
||||
final int dbCount,
|
||||
final HsHostingAssetType subAssetType) {
|
||||
return IntStream.range(0, userCount)
|
||||
.mapToObj(n -> HsHostingAssetEntity.builder()
|
||||
.type(directAssetType)
|
||||
.identifier(directAssetIdentifierFormat.formatted((n/'a')+'a', (n%'a')+'a'))
|
||||
.subHostingAssets(
|
||||
generate(dbCount, subAssetType, "%c%c.example.com".formatted((n/'a')+'a', (n%'a')+'a'))
|
||||
)
|
||||
.build())
|
||||
.toList();
|
||||
}
|
||||
|
||||
private List<HsHostingAssetEntity> generateDomainEmailSetupsWithEMailAddresses(
|
||||
final int domainCount,
|
||||
final HsHostingAssetType directAssetType,
|
||||
final String directAssetIdentifierFormat,
|
||||
final int emailAddressCount,
|
||||
final HsHostingAssetType subAssetType) {
|
||||
return IntStream.range(0, domainCount)
|
||||
.mapToObj(n -> HsHostingAssetEntity.builder()
|
||||
.type(directAssetType)
|
||||
.identifier(directAssetIdentifierFormat.formatted((n/'a')+'a', (n%'a')+'a'))
|
||||
.subHostingAssets(
|
||||
generate(emailAddressCount, subAssetType, "xyz00_%c%c%%c%%c".formatted((n/'a')+'a', (n%'a')+'a'))
|
||||
)
|
||||
.build())
|
||||
.toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,54 +1,66 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidators.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedWebspaceBookingItemValidatorUnitTest {
|
||||
|
||||
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
|
||||
.debitorNumber(12345)
|
||||
.build();
|
||||
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
|
||||
.debitor(debitor)
|
||||
.caption("Test-Project")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void validatesProperties() {
|
||||
// given
|
||||
final var mangedServerBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.project(project)
|
||||
.caption("Test Managed-Webspace")
|
||||
.resources(Map.ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 25),
|
||||
entry("SSD", 25),
|
||||
entry("Traffic", 250),
|
||||
entry("SLA-EMail", true)
|
||||
))
|
||||
.build();
|
||||
final var validator = forType(mangedServerBookingItemEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedServerBookingItemEntity);
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'resources.CPUs' is not expected but is set to '2'",
|
||||
"'resources.SLA-EMail' is not expected but is set to 'true'",
|
||||
"'resources.RAM' is not expected but is set to '25'");
|
||||
"'D-12345:Test-Project:Test Managed-Webspace.resources.CPUs' is not expected but is set to '2'",
|
||||
"'D-12345:Test-Project:Test Managed-Webspace.resources.RAM' is not expected but is set to '25'",
|
||||
"'D-12345:Test-Project:Test Managed-Webspace.resources.SSD' is required but missing",
|
||||
"'D-12345:Test-Project:Test Managed-Webspace.resources.SLA-EMail' is not expected but is set to 'true'"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsBookingItemEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
||||
"{type=integer, propertyName=SSD, required=true, unit=GB, min=1, max=100, step=1}",
|
||||
"{type=integer, propertyName=HDD, required=false, unit=GB, min=0, max=250, step=10}",
|
||||
"{type=integer, propertyName=Traffic, required=true, unit=GB, min=10, max=1000, step=10}",
|
||||
"{type=enumeration, propertyName=SLA-Platform, required=false, values=[BASIC, EXT24H]}",
|
||||
"{type=integer, propertyName=Daemons, required=false, unit=null, min=0, max=10, step=null}",
|
||||
"{type=boolean, propertyName=Online Office Server, required=false, falseIf=null}");
|
||||
"{type=integer, propertyName=SSD, unit=GB, min=1, max=100, step=1, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=HDD, unit=GB, min=0, max=250, step=10, required=false, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Traffic, unit=GB, min=10, max=1000, step=10, required=true, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Multi, min=1, max=100, step=1, required=false, defaultValue=1, isTotalsValidator=false}",
|
||||
"{type=integer, propertyName=Daemons, min=0, max=10, required=false, defaultValue=0, isTotalsValidator=false}",
|
||||
"{type=boolean, propertyName=Online Office Server, required=false, isTotalsValidator=false}",
|
||||
"{type=enumeration, propertyName=SLA-Platform, values=[BASIC, EXT24H], required=false, defaultValue=BASIC, isTotalsValidator=false}");
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,112 @@
|
||||
package net.hostsharing.hsadminng.hs.booking.item.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static java.util.List.of;
|
||||
import static java.util.Map.entry;
|
||||
import static java.util.Map.ofEntries;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsPrivateCloudBookingItemValidatorUnitTest {
|
||||
|
||||
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
|
||||
.debitorNumber(12345)
|
||||
.build();
|
||||
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
|
||||
.debitor(debitor)
|
||||
.caption("Test-Project")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void validatesPropertyTotals() {
|
||||
// given
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.type(PRIVATE_CLOUD)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build(),
|
||||
HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesExceedingPropertyTotals() {
|
||||
// given
|
||||
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
|
||||
.project(project)
|
||||
.type(PRIVATE_CLOUD)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 4),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 5000)
|
||||
))
|
||||
.subBookingItems(of(
|
||||
HsBookingItemEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 3),
|
||||
entry("RAM", 20),
|
||||
entry("SSD", 100),
|
||||
entry("Traffic", 3000)
|
||||
))
|
||||
.build(),
|
||||
HsBookingItemEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.resources(ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 10),
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 2500)
|
||||
))
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'D-12345:Test-Project:null.resources.CPUs' maximum total is 4, but actual total CPUs 5",
|
||||
"'D-12345:Test-Project:null.resources.RAM' maximum total is 20 GB, but actual total RAM 30 GB",
|
||||
"'D-12345:Test-Project:null.resources.SSD' maximum total is 100 GB, but actual total SSD 150 GB",
|
||||
"'D-12345:Test-Project:null.resources.Traffic' maximum total is 5000 GB, but actual total Traffic 5500 GB"
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.context.Context;
|
||||
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;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
@@ -23,7 +23,7 @@ import java.util.List;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||
import static net.hostsharing.hsadminng.rbac.test.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.mapper.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@@ -5,6 +5,7 @@ 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.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
@@ -20,8 +21,9 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hamcrest.Matchers.matchesRegex;
|
||||
@@ -77,25 +79,19 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
"type": "MANAGED_WEBSPACE",
|
||||
"identifier": "sec01",
|
||||
"caption": "some Webspace",
|
||||
"config": {
|
||||
"extra": 42
|
||||
}
|
||||
"config": {}
|
||||
},
|
||||
{
|
||||
"type": "MANAGED_WEBSPACE",
|
||||
"identifier": "fir01",
|
||||
"caption": "some Webspace",
|
||||
"config": {
|
||||
"extra": 42
|
||||
}
|
||||
"config": {}
|
||||
},
|
||||
{
|
||||
"type": "MANAGED_WEBSPACE",
|
||||
"identifier": "thi01",
|
||||
"caption": "some Webspace",
|
||||
"config": {
|
||||
"extra": 42
|
||||
}
|
||||
"config": {}
|
||||
}
|
||||
]
|
||||
"""));
|
||||
@@ -110,41 +106,47 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-user", "superuser-alex@hostsharing.net")
|
||||
.port(port)
|
||||
.header("current-user", "superuser-alex@hostsharing.net")
|
||||
.port(port)
|
||||
.when()
|
||||
.get("http://localhost/api/hs/hosting/assets?type=" + MANAGED_SERVER)
|
||||
. get("http://localhost/api/hs/hosting/assets?type=" + MANAGED_SERVER)
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(200)
|
||||
.contentType("application/json")
|
||||
.body("", lenientlyEquals("""
|
||||
[
|
||||
{
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1011",
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"extra": 42
|
||||
.statusCode(200)
|
||||
.contentType("application/json")
|
||||
.body("", lenientlyEquals("""
|
||||
[
|
||||
{
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1011",
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"monit_max_cpu_usage": 90,
|
||||
"monit_max_ram_usage": 80,
|
||||
"monit_max_ssd_usage": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1012",
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"monit_max_cpu_usage": 90,
|
||||
"monit_max_ram_usage": 80,
|
||||
"monit_max_ssd_usage": 70
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1013",
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"monit_max_cpu_usage": 90,
|
||||
"monit_max_ram_usage": 80,
|
||||
"monit_max_ssd_usage": 70
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1012",
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"extra": 42
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1013",
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"extra": 42
|
||||
}
|
||||
}
|
||||
]
|
||||
"""));
|
||||
]
|
||||
"""));
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
@@ -156,7 +158,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
void globalAdmin_canAddBookedAsset() {
|
||||
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItem = givenBookingItem("D-1000111 default project", "some PrivateCloud");
|
||||
final var givenBookingItem = newBookingItem("D-1000111 default project",
|
||||
HsBookingItemType.MANAGED_WEBSPACE, "separate ManagedWebspace BI",
|
||||
Map.ofEntries(
|
||||
entry("SSD", 50),
|
||||
entry("Traffic", 50)
|
||||
)
|
||||
);
|
||||
final var givenParentAsset = givenParentAsset(MANAGED_SERVER, "vm1011");
|
||||
|
||||
final var location = RestAssured // @formatter:off
|
||||
.given()
|
||||
@@ -165,12 +174,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.body("""
|
||||
{
|
||||
"bookingItemUuid": "%s",
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1400",
|
||||
"caption": "some new ManagedServer",
|
||||
"config": { "monit_max_ssd_usage": 80, "monit_max_cpu_usage": 90, "monit_max_ram_usage": 70 }
|
||||
"type": "MANAGED_WEBSPACE",
|
||||
"identifier": "fir10",
|
||||
"parentAssetUuid": "%s",
|
||||
"caption": "some separate ManagedWebspace HA",
|
||||
"config": {}
|
||||
}
|
||||
""".formatted(givenBookingItem.getUuid()))
|
||||
""".formatted(givenBookingItem.getUuid(), givenParentAsset.getUuid()))
|
||||
.port(port)
|
||||
.when()
|
||||
.post("http://localhost/api/hs/hosting/assets")
|
||||
@@ -179,19 +189,20 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.contentType(ContentType.JSON)
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"type": "MANAGED_SERVER",
|
||||
"identifier": "vm1400",
|
||||
"caption": "some new ManagedServer",
|
||||
"config": { "monit_max_ssd_usage": 80, "monit_max_cpu_usage": 90, "monit_max_ram_usage": 70 }
|
||||
"type": "MANAGED_WEBSPACE",
|
||||
"identifier": "fir10",
|
||||
"caption": "some separate ManagedWebspace HA",
|
||||
"config": {}
|
||||
}
|
||||
"""))
|
||||
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
||||
.extract().header("Location"); // @formatter:on
|
||||
|
||||
// finally, the new asset can be accessed under the generated UUID
|
||||
final var newUserUuid = UUID.fromString(
|
||||
final var newWebspace = UUID.fromString(
|
||||
location.substring(location.lastIndexOf('/') + 1));
|
||||
assertThat(newUserUuid).isNotNull();
|
||||
assertThat(newWebspace).isNotNull();
|
||||
toCleanup(HsHostingAssetEntity.class, newWebspace);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -240,7 +251,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
}
|
||||
|
||||
@Test
|
||||
void additionalValidationsArePerformend_whenAddingAsset() {
|
||||
void propertyValidationsArePerformend_whenAddingAsset() {
|
||||
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItem = givenBookingItem("D-1000111 default project", "some PrivateCloud");
|
||||
@@ -267,9 +278,66 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"statusPhrase": "Bad Request",
|
||||
"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]"
|
||||
"message": "[
|
||||
<<<'MANAGED_SERVER:vm1400.config.extra' is not expected but is set to '42',
|
||||
<<<'MANAGED_SERVER:vm1400.config.monit_max_ssd_usage' is expected to be >= 10 but is 0,
|
||||
<<<'MANAGED_SERVER:vm1400.config.monit_max_cpu_usage' is expected to be <= 100 but is 101,
|
||||
<<<'MANAGED_SERVER:vm1400.config.monit_max_ram_usage' is required but missing
|
||||
<<<]"
|
||||
}
|
||||
""")); // @formatter:on
|
||||
""".replaceAll(" +<<<", ""))); // @formatter:on
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void totalsLimitValidationsArePerformend_whenAddingAsset() {
|
||||
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenHostingAsset = givenHostingAsset(MANAGED_WEBSPACE, "fir01");
|
||||
assertThat(givenHostingAsset.getBookingItem().getResources().get("Multi"))
|
||||
.as("precondition failed")
|
||||
.isEqualTo(1);
|
||||
|
||||
jpaAttempt.transacted(() -> {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
for (int n = 0; n < 25; ++n ) {
|
||||
toCleanup(assetRepo.save(
|
||||
HsHostingAssetEntity.builder()
|
||||
.type(UNIX_USER)
|
||||
.parentAsset(givenHostingAsset)
|
||||
.identifier("fir01-%2d".formatted(n))
|
||||
.caption("Test UnixUser fir01-%2d".formatted(n))
|
||||
.build()));
|
||||
}
|
||||
}).assertSuccessful();
|
||||
|
||||
RestAssured // @formatter:off
|
||||
.given()
|
||||
.header("current-user", "superuser-alex@hostsharing.net")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
"parentAssetUuid": "%s",
|
||||
"type": "UNIX_USER",
|
||||
"identifier": "fir01-extra",
|
||||
"caption": "some extra UnixUser",
|
||||
"config": { }
|
||||
}
|
||||
""".formatted(givenHostingAsset.getUuid()))
|
||||
.port(port)
|
||||
.when()
|
||||
.post("http://localhost/api/hs/hosting/assets")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(400)
|
||||
.contentType(ContentType.JSON)
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"statusPhrase": "Bad Request",
|
||||
"message": "[
|
||||
<<<'D-1000111:D-1000111 default project:separate ManagedWebspace.resources.Multi=1 allows at maximum 25 unix users, but 26 found
|
||||
<<<]"
|
||||
}
|
||||
""".replaceAll(" +<<<", ""))); // @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,9 +363,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"extra": 42
|
||||
}
|
||||
"config": {}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
}
|
||||
@@ -340,9 +406,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
{
|
||||
"identifier": "vm1013",
|
||||
"caption": "some ManagedServer",
|
||||
"config": {
|
||||
"extra": 42
|
||||
}
|
||||
"config": {}
|
||||
}
|
||||
""")); // @formatter:on
|
||||
}
|
||||
@@ -443,6 +507,29 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
||||
}
|
||||
}
|
||||
|
||||
HsHostingAssetEntity givenHostingAsset(final HsHostingAssetType type, final String identifier) {
|
||||
return assetRepo.findByIdentifier(identifier).stream()
|
||||
.filter(ha -> ha.getType()==type)
|
||||
.findAny().orElseThrow();
|
||||
}
|
||||
|
||||
HsBookingItemEntity newBookingItem(
|
||||
final String projectCaption,
|
||||
final HsBookingItemType type, final String bookingItemCaption, final Map<String, Object> resources) {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var project = projectRepo.findByCaption(projectCaption).stream()
|
||||
.findAny().orElseThrow();
|
||||
final var bookingItem = HsBookingItemEntity.builder()
|
||||
.project(project)
|
||||
.type(type)
|
||||
.caption(bookingItemCaption)
|
||||
.resources(resources)
|
||||
.build();
|
||||
return toCleanup(bookingItemRepo.save(bookingItem));
|
||||
}).assertSuccessful().returnedValue();
|
||||
}
|
||||
|
||||
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
|
||||
return bookingItemRepo.findByCaption(bookingItemCaption).stream()
|
||||
.filter(bi -> bi.getRelatedProject().getCaption().contains(projectCaption))
|
||||
|
@@ -40,11 +40,11 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
||||
private static final Map<String, Object> PATCH_CONFIG = patchMap(
|
||||
entry("CPU", 2),
|
||||
entry("HDD", null),
|
||||
entry("SDD", 256)
|
||||
entry("SSD", 256)
|
||||
);
|
||||
private static final Map<String, Object> PATCHED_CONFIG = patchMap(
|
||||
entry("CPU", 2),
|
||||
entry("SDD", 256),
|
||||
entry("SSD", 256),
|
||||
entry("MEM", 64)
|
||||
);
|
||||
|
||||
|
@@ -33,7 +33,8 @@ class HsHostingAssetPropsControllerAcceptanceTest {
|
||||
[
|
||||
"MANAGED_SERVER",
|
||||
"MANAGED_WEBSPACE",
|
||||
"CLOUD_SERVER"
|
||||
"CLOUD_SERVER",
|
||||
"UNIX_USER"
|
||||
]
|
||||
"""));
|
||||
// @formatter:on
|
||||
@@ -55,56 +56,54 @@ class HsHostingAssetPropsControllerAcceptanceTest {
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "monit_min_free_ssd",
|
||||
"required": false,
|
||||
"unit": null,
|
||||
"min": 1,
|
||||
"max": 1000,
|
||||
"step": null
|
||||
"required": false,
|
||||
"isTotalsValidator": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "monit_min_free_hdd",
|
||||
"required": false,
|
||||
"unit": null,
|
||||
"min": 1,
|
||||
"max": 4000,
|
||||
"step": null
|
||||
"required": false,
|
||||
"isTotalsValidator": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "monit_max_ssd_usage",
|
||||
"required": true,
|
||||
"unit": "%",
|
||||
"min": 10,
|
||||
"max": 100,
|
||||
"step": null
|
||||
"required": true,
|
||||
"isTotalsValidator": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "monit_max_hdd_usage",
|
||||
"required": false,
|
||||
"unit": "%",
|
||||
"min": 10,
|
||||
"max": 100,
|
||||
"step": null
|
||||
"required": false,
|
||||
"isTotalsValidator": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "monit_max_cpu_usage",
|
||||
"required": true,
|
||||
"unit": "%",
|
||||
"min": 10,
|
||||
"max": 100,
|
||||
"step": null
|
||||
"required": true,
|
||||
"isTotalsValidator": false
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"propertyName": "monit_max_ram_usage",
|
||||
"required": true,
|
||||
"unit": "%",
|
||||
"min": 10,
|
||||
"max": 100,
|
||||
"step": null
|
||||
"required": true,
|
||||
"isTotalsValidator": false
|
||||
}
|
||||
]
|
||||
"""));
|
||||
|
@@ -3,10 +3,11 @@ package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||
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.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
@@ -30,7 +31,7 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANA
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||
import static net.hostsharing.hsadminng.rbac.test.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.mapper.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -70,12 +71,13 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var count = assetRepo.count();
|
||||
final var givenManagedServer = givenManagedServer("D-1000111 default project", MANAGED_SERVER);
|
||||
final var givenManagedServer = givenHostingAsset("D-1000111 default project", MANAGED_SERVER);
|
||||
final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01");
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> {
|
||||
final var newAsset = HsHostingAssetEntity.builder()
|
||||
.bookingItem(givenManagedServer.getBookingItem())
|
||||
.bookingItem(newWebspaceBookingItem)
|
||||
.parentAsset(givenManagedServer)
|
||||
.caption("some new managed webspace")
|
||||
.type(MANAGED_WEBSPACE)
|
||||
@@ -95,18 +97,19 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
public void createsAndGrantsRoles() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var givenManagedServer = givenHostingAsset("D-1000111 default project", MANAGED_SERVER);
|
||||
final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01");
|
||||
em.flush();
|
||||
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
|
||||
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()).stream()
|
||||
.map(s -> s.replace("hs_office_", ""))
|
||||
.toList();
|
||||
final var givenBookingItem = givenBookingItem("D-1000111 default project", "some PrivateCloud");
|
||||
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
|
||||
|
||||
// when
|
||||
final var result = attempt(em, () -> {
|
||||
final var newAsset = HsHostingAssetEntity.builder()
|
||||
.bookingItem(givenBookingItem)
|
||||
.type(HsHostingAssetType.MANAGED_SERVER)
|
||||
.identifier("vm9000")
|
||||
.bookingItem(newWebspaceBookingItem)
|
||||
.parentAsset(givenManagedServer)
|
||||
.type(HsHostingAssetType.MANAGED_WEBSPACE)
|
||||
.identifier("fir00")
|
||||
.caption("some new managed webspace")
|
||||
.build();
|
||||
return toCleanup(assetRepo.save(newAsset));
|
||||
@@ -117,29 +120,33 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
final var all = rawRoleRepo.findAll();
|
||||
assertThat(distinctRoleNamesOf(all)).containsExactlyInAnyOrder(Array.from(
|
||||
initialRoleNames,
|
||||
"hs_hosting_asset#vm9000:OWNER",
|
||||
"hs_hosting_asset#vm9000:ADMIN",
|
||||
"hs_hosting_asset#vm9000:AGENT",
|
||||
"hs_hosting_asset#vm9000:TENANT"));
|
||||
"hs_hosting_asset#fir00:ADMIN",
|
||||
"hs_hosting_asset#fir00:AGENT",
|
||||
"hs_hosting_asset#fir00:OWNER",
|
||||
"hs_hosting_asset#fir00:TENANT"));
|
||||
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
|
||||
.map(s -> s.replace("hs_office_", ""))
|
||||
.containsExactlyInAnyOrder(fromFormatted(
|
||||
initialGrantNames,
|
||||
|
||||
// owner
|
||||
"{ grant role:hs_hosting_asset#vm9000:OWNER to role:hs_booking_item#somePrivateCloud:ADMIN by system and assume }",
|
||||
"{ grant perm:hs_hosting_asset#vm9000:DELETE to role:hs_hosting_asset#vm9000:OWNER by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#vm9000:ADMIN to role:hs_hosting_asset#vm9000:OWNER by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#fir00:OWNER to role:hs_booking_item#fir01:ADMIN by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#fir00:OWNER to role:hs_hosting_asset#vm1011:ADMIN by system and assume }",
|
||||
"{ grant perm:hs_hosting_asset#fir00:DELETE to role:hs_hosting_asset#fir00:OWNER by system and assume }",
|
||||
|
||||
// admin
|
||||
"{ grant perm:hs_hosting_asset#vm9000:INSERT>hs_hosting_asset to role:hs_hosting_asset#vm9000:ADMIN by system and assume }",
|
||||
"{ grant perm:hs_hosting_asset#vm9000:UPDATE to role:hs_hosting_asset#vm9000:ADMIN by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#vm9000:ADMIN to role:hs_booking_item#somePrivateCloud:AGENT by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#vm9000:TENANT to role:hs_hosting_asset#vm9000:AGENT by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#vm9000:AGENT to role:hs_hosting_asset#vm9000:ADMIN by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#fir00:ADMIN to role:hs_hosting_asset#fir00:OWNER by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#fir00:ADMIN to role:hs_booking_item#fir01:AGENT by system and assume }",
|
||||
"{ grant perm:hs_hosting_asset#fir00:INSERT>hs_hosting_asset to role:hs_hosting_asset#fir00:ADMIN by system and assume }",
|
||||
"{ grant perm:hs_hosting_asset#fir00:UPDATE to role:hs_hosting_asset#fir00:ADMIN by system and assume }",
|
||||
|
||||
// agent
|
||||
"{ grant role:hs_hosting_asset#fir00:ADMIN to role:hs_hosting_asset#vm1011:AGENT by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#fir00:AGENT to role:hs_hosting_asset#fir00:ADMIN by system and assume }",
|
||||
|
||||
// tenant
|
||||
"{ grant role:hs_booking_item#somePrivateCloud:TENANT to role:hs_hosting_asset#vm9000:TENANT by system and assume }",
|
||||
"{ grant role:hs_booking_item#fir01:TENANT to role:hs_hosting_asset#fir00:TENANT by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#fir00:TENANT to role:hs_hosting_asset#fir00:AGENT by system and assume }",
|
||||
"{ grant role:hs_hosting_asset#vm1011:TENANT to role:hs_hosting_asset#fir00:TENANT by system and assume }",
|
||||
|
||||
null));
|
||||
}
|
||||
@@ -164,9 +171,9 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
// then
|
||||
allTheseServersAreReturned(
|
||||
result,
|
||||
"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 })");
|
||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)",
|
||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedWebspace)",
|
||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedWebspace)");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -182,9 +189,8 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
// then:
|
||||
exactlyTheseAssetsAreReturned(
|
||||
result,
|
||||
"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 })");
|
||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedWebspace)",
|
||||
"HsHostingAssetEntity(MANAGED_SERVER, vm1011, some ManagedServer, D-1000111:D-1000111 default project:separate ManagedServer, { monit_max_cpu_usage: 90, monit_max_ram_usage: 80, monit_max_ssd_usage: 70 })");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -200,7 +206,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, { extra: 42 })");
|
||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -351,7 +357,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
private HsHostingAssetEntity givenSomeTemporaryAsset(final String projectCaption, final String identifier) {
|
||||
return jpaAttempt.transacted(() -> {
|
||||
context("superuser-alex@hostsharing.net");
|
||||
final var givenBookingItem = givenBookingItem("D-1000111 default project", "some PrivateCloud");
|
||||
final var givenBookingItem = givenBookingItem("D-1000111 default project", "test CloudServer");
|
||||
final var newAsset = HsHostingAssetEntity.builder()
|
||||
.bookingItem(givenBookingItem)
|
||||
.type(CLOUD_SERVER)
|
||||
@@ -367,20 +373,30 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
||||
}
|
||||
|
||||
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
|
||||
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
|
||||
.findAny().orElseThrow();
|
||||
return bookingItemRepo.findAllByProjectUuid(givenProject.getUuid()).stream()
|
||||
.filter(i -> i.getCaption().equals(bookingItemCaption))
|
||||
return bookingItemRepo.findByCaption(bookingItemCaption).stream()
|
||||
.filter(i -> i.getRelatedProject().getCaption().equals(projectCaption))
|
||||
.findAny().orElseThrow();
|
||||
}
|
||||
|
||||
HsHostingAssetEntity givenManagedServer(final String projectCaption, final HsHostingAssetType type) {
|
||||
HsHostingAssetEntity givenHostingAsset(final String projectCaption, final HsHostingAssetType type) {
|
||||
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
|
||||
.findAny().orElseThrow();
|
||||
return assetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream()
|
||||
.findAny().orElseThrow();
|
||||
}
|
||||
|
||||
HsBookingItemEntity newBookingItem(
|
||||
final HsBookingItemEntity parentBookingItem,
|
||||
final HsBookingItemType type,
|
||||
final String caption) {
|
||||
final var newBookingItem = HsBookingItemEntity.builder()
|
||||
.parentItem(parentBookingItem)
|
||||
.type(type)
|
||||
.caption(caption)
|
||||
.build();
|
||||
return toCleanup(bookingItemRepo.save(newBookingItem));
|
||||
}
|
||||
|
||||
void exactlyTheseAssetsAreReturned(
|
||||
final List<HsHostingAssetEntity> actualResult,
|
||||
final String... serverNames) {
|
||||
|
@@ -7,7 +7,6 @@ import java.util.Map;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
|
||||
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidators.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
@@ -17,24 +16,25 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
||||
// given
|
||||
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(CLOUD_SERVER)
|
||||
.identifier("vm1234")
|
||||
.config(Map.ofEntries(
|
||||
entry("RAM", 2000)
|
||||
))
|
||||
.build();
|
||||
final var validator = forType(cloudServerHostingAssetEntity.getType());
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(cloudServerHostingAssetEntity.getType());
|
||||
|
||||
|
||||
// when
|
||||
final var result = validator.validate(cloudServerHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'config.RAM' is not expected but is set to '2000'");
|
||||
assertThat(result).containsExactly("'CLOUD_SERVER:vm1234.config.RAM' is not expected but is set to '2000'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void containsAllValidations() {
|
||||
// when
|
||||
final var validator = forType(CLOUD_SERVER);
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(CLOUD_SERVER);
|
||||
|
||||
// then
|
||||
assertThat(validator.properties()).map(Map::toString).isEmpty();
|
||||
|
@@ -6,27 +6,27 @@ import org.junit.jupiter.api.Test;
|
||||
import jakarta.validation.ValidationException;
|
||||
|
||||
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;
|
||||
|
||||
class HsHostingAssetEntityValidatorsUnitTest {
|
||||
class HsHostingAssetEntityValidatorUnitTest {
|
||||
|
||||
@Test
|
||||
void validThrowsException() {
|
||||
// given
|
||||
final var managedServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.identifier("vm1234")
|
||||
.build();
|
||||
|
||||
// when
|
||||
final var result = catchThrowable( ()-> valid(managedServerHostingAssetEntity) );
|
||||
final var result = catchThrowable( ()-> HsHostingAssetEntityValidatorRegistry.validated(managedServerHostingAssetEntity));
|
||||
|
||||
// then
|
||||
assertThat(result).isInstanceOf(ValidationException.class)
|
||||
.hasMessageContaining(
|
||||
"'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");
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_ssd_usage' is required but missing",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_cpu_usage' is required but missing",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_ram_usage' is required but missing");
|
||||
}
|
||||
}
|
@@ -7,7 +7,6 @@ import java.util.Map;
|
||||
|
||||
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.validators.HsHostingAssetEntityValidators.forType;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
@@ -17,22 +16,23 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
||||
// given
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.identifier("vm1234")
|
||||
.config(Map.ofEntries(
|
||||
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());
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(mangedWebspaceHostingAssetEntity.getType());
|
||||
|
||||
// when
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactlyInAnyOrder(
|
||||
"'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");
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_cpu_usage' is expected to be >= 10 but is 2",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_ram_usage' is expected to be <= 100 but is 101",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_ssd_usage' is required but missing",
|
||||
"'MANAGED_SERVER:vm1234.config.monit_max_hdd_usage' is expected to be of type class java.lang.Integer, but is of type 'String'");
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
||||
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
|
||||
@@ -16,21 +17,32 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
|
||||
final HsBookingItemEntity managedServerBookingItem = HsBookingItemEntity.builder()
|
||||
.project(TEST_PROJECT)
|
||||
.type(HsBookingItemType.MANAGED_SERVER)
|
||||
.caption("Test Managed-Server")
|
||||
.resources(Map.ofEntries(
|
||||
entry("CPUs", 2),
|
||||
entry("RAM", 25),
|
||||
entry("SSD", 25),
|
||||
entry("Traffic", 250),
|
||||
entry("SLA-Platform", "EXT4H"),
|
||||
entry("SLA-EMail", true)
|
||||
))
|
||||
.build();
|
||||
final HsHostingAssetEntity mangedServerAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_SERVER)
|
||||
.type(HsHostingAssetType.MANAGED_SERVER)
|
||||
.bookingItem(managedServerBookingItem)
|
||||
.identifier("vm1234")
|
||||
.config(Map.ofEntries(
|
||||
entry("HDD", 0),
|
||||
entry("SSD", 1),
|
||||
entry("Traffic", 10)
|
||||
entry("monit_max_ssd_usage", 70),
|
||||
entry("monit_max_cpu_usage", 80),
|
||||
entry("monit_max_ram_usage", 90)
|
||||
))
|
||||
.build();
|
||||
|
||||
@Test
|
||||
void validatesIdentifier() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
@@ -47,7 +59,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
@Test
|
||||
void validatesUnknownProperties() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
@@ -61,13 +73,13 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
||||
|
||||
// then
|
||||
assertThat(result).containsExactly("'config.unknown' is not expected but is set to 'some value'");
|
||||
assertThat(result).containsExactly("'MANAGED_WEBSPACE:abc00.config.unknown' is not expected but is set to 'some value'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesValidEntity() {
|
||||
// given
|
||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
||||
final var validator = HsHostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
|
||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||
.type(MANAGED_WEBSPACE)
|
||||
.parentAsset(mangedServerAssetEntity)
|
||||
|
@@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
|
@@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
|
@@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipReposito
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@@ -5,7 +5,7 @@ import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipReposito
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@@ -11,7 +11,7 @@ import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.hibernate.Hibernate;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
@@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@@ -30,7 +30,7 @@ import java.util.Objects;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacObjectEntity.objectDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||
import static net.hostsharing.hsadminng.rbac.test.Array.from;
|
||||
import static net.hostsharing.hsadminng.mapper.Array.from;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
|
@@ -6,7 +6,7 @@ import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@@ -7,7 +7,7 @@ import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -26,7 +26,7 @@ import java.util.List;
|
||||
|
||||
import static net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantEntity.distinctGrantDisplaysOf;
|
||||
import static net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleEntity.distinctRoleNamesOf;
|
||||
import static net.hostsharing.hsadminng.rbac.test.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.mapper.Array.fromFormatted;
|
||||
import static net.hostsharing.hsadminng.rbac.test.JpaAttempt.attempt;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.context;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacrole;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||
import net.hostsharing.hsadminng.mapper.Array;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@@ -1,40 +0,0 @@
|
||||
package net.hostsharing.hsadminng.rbac.test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Java has List.of(...), Set.of(...) and Map.of(...) all with varargs parameter,
|
||||
* but no Array.of(...). Here it is.
|
||||
*/
|
||||
public class Array {
|
||||
|
||||
@SafeVarargs
|
||||
public static <E> E[] of(E... elements) {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static String[] from(final List<String> initialList, final String... additionalStrings) {
|
||||
final var resultList = new ArrayList<>(initialList);
|
||||
resultList.addAll(Arrays.stream(additionalStrings).toList());
|
||||
return resultList.toArray(String[]::new);
|
||||
}
|
||||
|
||||
public static String[] fromFormatted(final List<String> initialList, final String... additionalStrings) {
|
||||
final var resultList = new ArrayList<>(initialList);
|
||||
resultList.addAll(Arrays.stream(additionalStrings)
|
||||
.filter(Objects::nonNull)
|
||||
.map(s -> s.replaceAll(" *", " "))
|
||||
.toList());
|
||||
return resultList.toArray(String[]::new);
|
||||
}
|
||||
|
||||
public static String[] from(final String[] initialStrings, final String... additionalStrings) {
|
||||
final var resultList = Arrays.asList(initialStrings);
|
||||
resultList.addAll(Arrays.stream(additionalStrings).toList());
|
||||
return resultList.toArray(String[]::new);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user