1
0

add optional alarm-contact to hosting-asset (#64)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/64
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-06-21 12:02:07 +02:00
parent d157730de7
commit 9418303b7c
17 changed files with 544 additions and 286 deletions

View File

@@ -150,7 +150,8 @@ public class ArchitectureTest {
.should().onlyBeAccessed().byClassesThat()
.resideInAnyPackage(
"..hs.booking.(*)..",
"..hs.hosting.(*).."
"..hs.hosting.(*)..",
"..hs.validation" // TODO.impl: Some Validators need to be refactored to booking package.
);
@ArchTest
@@ -195,7 +196,9 @@ public class ArchitectureTest {
"..hs.office.partner..",
"..hs.office.debitor..",
"..hs.office.membership..",
"..hs.office.migration..");
"..hs.office.migration..",
"..hs.hosting.asset.."
);
@ArchTest
@SuppressWarnings("unused")

View File

@@ -97,9 +97,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()).stream()
.map(s -> s.replace("hs_office_", ""))
.toList();
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
// when
attempt(em, () -> {
@@ -124,7 +122,6 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
"hs_booking_item#somenewbookingitem:OWNER",
"hs_booking_item#somenewbookingitem:TENANT"));
assertThat(distinctGrantDisplaysOf(rawGrantRepo.findAll()))
.map(s -> s.replace("hs_office_", ""))
.containsExactlyInAnyOrder(fromFormatted(
initialGrantNames,
@@ -138,7 +135,6 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// admin
"{ grant perm:hs_booking_item#somenewbookingitem:UPDATE to role:hs_booking_item#somenewbookingitem:ADMIN by system and assume }",
"{ grant role:hs_booking_item#somenewbookingitem:ADMIN to role:hs_booking_item#somenewbookingitem:OWNER by system and assume }",
"{ grant perm:hs_booking_item#somenewbookingitem:INSERT>hs_hosting_asset to role:hs_booking_item#somenewbookingitem:AGENT by system and assume }",
// agent
"{ grant role:hs_booking_item#somenewbookingitem:AGENT to role:hs_booking_item#somenewbookingitem:ADMIN by system and assume }",

View File

@@ -7,6 +7,8 @@ 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.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
@@ -54,6 +56,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Autowired
HsOfficeDebitorRepository debitorRepo;
@Autowired
HsOfficeContactRepository contactRepo;
@Autowired
JpaAttempt jpaAttempt;
@@ -425,6 +430,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
final var givenAsset = givenSomeTemporaryHostingAsset("2001", MANAGED_SERVER,
config("monit_max_ssd_usage", 80), config("monit_max_hdd_usage", 90), config("monit_max_cpu_usage", 90), config("monit_max_ram_usage", 70));
final var alarmContactUuid = givenContact().getUuid();
RestAssured // @formatter:off
.given()
@@ -432,13 +438,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
.contentType(ContentType.JSON)
.body("""
{
"alarmContactUuid": "%s",
"config": {
"monit_max_ssd_usage": 85,
"monit_max_hdd_usage": null,
"monit_min_free_ssd": 5
}
}
""")
""".formatted(alarmContactUuid))
.port(port)
.when()
.patch("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
@@ -450,6 +457,11 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
"type": "MANAGED_SERVER",
"identifier": "vm2001",
"caption": "some test-asset",
"alarmContact": {
"uuid": "%s",
"caption": "second contact",
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
},
"config": {
"monit_max_cpu_usage": 90,
"monit_max_ram_usage": 70,
@@ -457,12 +469,15 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
"monit_min_free_ssd": 5
}
}
""")); // @formatter:on
""".formatted(alarmContactUuid)));
// @formatter:on
// finally, the asset is actually updated
context.define("superuser-alex@hostsharing.net");
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
.matches(asset -> {
assertThat(asset.getAlarmContact().toString()).isEqualTo(
"contact(caption='second contact', emailAddresses='{ main: contact-admin@secondcontact.example.com }')");
assertThat(asset.getConfig().toString()).isEqualTo(
"{ monit_max_cpu_usage: 90, monit_max_ram_usage: 70, monit_max_ssd_usage: 85, monit_min_free_ssd: 5 }");
return true;
@@ -470,6 +485,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
}
}
private HsOfficeContactEntity givenContact() {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
return contactRepo.findContactByOptionalCaptionLike("second").stream().findFirst().orElseThrow();
}).returnedValue();
}
@Nested
@Order(5)
class DeleteAsset {

View File

@@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactEntity;
import net.hostsharing.hsadminng.mapper.KeyValueMap;
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
import org.junit.jupiter.api.BeforeEach;
@@ -31,6 +31,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
> {
private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID();
private static final UUID PATCHED_CONTACT_UUID = UUID.randomUUID();
private static final Map<String, Object> INITIAL_CONFIG = patchMap(
entry("CPU", 1),
@@ -47,6 +48,9 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
entry("SSD", 256),
entry("MEM", 64)
);
final HsOfficeContactEntity givenInitialContact = HsOfficeContactEntity.builder()
.uuid(UUID.randomUUID())
.build();
private static final String INITIAL_CAPTION = "initial caption";
private static final String PATCHED_CAPTION = "patched caption";
@@ -56,10 +60,10 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
@BeforeEach
void initMocks() {
lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsHostingAssetEntity.class), any())).thenAnswer(invocation ->
HsHostingAssetEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsOfficeContactEntity.class), any())).thenAnswer(invocation ->
HsOfficeContactEntity.builder().uuid(invocation.getArgument(1)).build());
}
@Override
@@ -69,6 +73,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
entity.setBookingItem(TEST_BOOKING_ITEM);
entity.getConfig().putAll(KeyValueMap.from(INITIAL_CONFIG));
entity.setCaption(INITIAL_CAPTION);
entity.setAlarmContact(givenInitialContact);
return entity;
}
@@ -79,7 +84,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
@Override
protected HsHostingAssetEntityPatcher createPatcher(final HsHostingAssetEntity server) {
return new HsHostingAssetEntityPatcher(server);
return new HsHostingAssetEntityPatcher(em, server);
}
@Override
@@ -96,7 +101,17 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
PATCH_CONFIG,
HsHostingAssetEntity::putConfig,
PATCHED_CONFIG)
.notNullable()
.notNullable(),
new JsonNullableProperty<>(
"alarmContact",
HsHostingAssetPatchResource::setAlarmContactUuid,
PATCHED_CONTACT_UUID,
HsHostingAssetEntity::setAlarmContact,
newContact(PATCHED_CONTACT_UUID))
);
}
static HsOfficeContactEntity newContact(final UUID uuid) {
return HsOfficeContactEntity.builder().uuid(uuid).build();
}
}

View File

@@ -147,6 +147,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
"{ 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 }",
"{ grant perm:hs_hosting_asset#fir00:SELECT to role:hs_hosting_asset#fir00:TENANT by system and assume }",
null));
}