Compare commits
No commits in common. "cb29730810012d9120f37cd7fda9f677fe1761e8" and "d7a57fd112394d31458a11d5a3060fad5ac3a6a2" have entirely different histories.
cb29730810
...
d7a57fd112
@ -16,9 +16,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import jakarta.persistence.EntityNotFoundException;
|
import jakarta.persistence.EntityNotFoundException;
|
||||||
import jakarta.persistence.PersistenceContext;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
@ -28,9 +26,6 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAss
|
|||||||
@RestController
|
@RestController
|
||||||
public class HsHostingAssetController implements HsHostingAssetsApi {
|
public class HsHostingAssetController implements HsHostingAssetsApi {
|
||||||
|
|
||||||
@PersistenceContext
|
|
||||||
private EntityManager em;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
@ -124,7 +119,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
|
|||||||
|
|
||||||
final var current = assetRepo.findByUuid(assetUuid).orElseThrow();
|
final var current = assetRepo.findByUuid(assetUuid).orElseThrow();
|
||||||
|
|
||||||
new HsHostingAssetEntityPatcher(em, current).apply(body);
|
new HsHostingAssetEntityPatcher(current).apply(body);
|
||||||
|
|
||||||
final var saved = validated(assetRepo.save(current));
|
final var saved = validated(assetRepo.save(current));
|
||||||
final var mapped = mapper.map(saved, HsHostingAssetResource.class);
|
final var mapped = mapper.map(saved, HsHostingAssetResource.class);
|
||||||
|
@ -100,7 +100,7 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject {
|
|||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name = "alarmcontactuuid")
|
@JoinColumn(name = "alarmcontactuuid")
|
||||||
private HsHostingContactEntity alarmContact;
|
private HsHostingContactEntity alarmContactUuid;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
|
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
|
||||||
@JoinColumn(name="parentassetuuid", referencedColumnName="uuid")
|
@JoinColumn(name="parentassetuuid", referencedColumnName="uuid")
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.contact.HsHostingContactEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
|
||||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||||
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
||||||
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
import net.hostsharing.hsadminng.mapper.OptionalFromJson;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAssetPatchResource> {
|
public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAssetPatchResource> {
|
||||||
|
|
||||||
private final EntityManager em;
|
|
||||||
private final HsHostingAssetEntity entity;
|
private final HsHostingAssetEntity entity;
|
||||||
|
|
||||||
HsHostingAssetEntityPatcher(final EntityManager em, final HsHostingAssetEntity entity) {
|
public HsHostingAssetEntityPatcher(final HsHostingAssetEntity entity) {
|
||||||
this.em = em;
|
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,15 +21,5 @@ public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAsset
|
|||||||
.ifPresent(entity::setCaption);
|
.ifPresent(entity::setCaption);
|
||||||
Optional.ofNullable(resource.getConfig())
|
Optional.ofNullable(resource.getConfig())
|
||||||
.ifPresent(r -> entity.getConfig().patch(KeyValueMap.from(resource.getConfig())));
|
.ifPresent(r -> entity.getConfig().patch(KeyValueMap.from(resource.getConfig())));
|
||||||
OptionalFromJson.of(resource.getAlarmContactUuid()).ifPresent(newValue -> {
|
|
||||||
verifyNotNull(newValue, "alarmContact");
|
|
||||||
entity.setAlarmContact(em.getReference(HsHostingContactEntity.class, newValue));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifyNotNull(final UUID newValue, final String propertyName) {
|
|
||||||
if (newValue == null) {
|
|
||||||
throw new IllegalArgumentException("property '" + propertyName + "' must not be null");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,6 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
caption:
|
caption:
|
||||||
type: string
|
type: string
|
||||||
alarmContact:
|
|
||||||
$ref: '../hs-office/hs-office-contact-schemas.yaml#/components/schemas/HsOfficeContact'
|
|
||||||
config:
|
config:
|
||||||
$ref: '#/components/schemas/HsHostingAssetConfiguration'
|
$ref: '#/components/schemas/HsHostingAssetConfiguration'
|
||||||
required:
|
required:
|
||||||
@ -48,10 +46,6 @@ components:
|
|||||||
caption:
|
caption:
|
||||||
type: string
|
type: string
|
||||||
nullable: true
|
nullable: true
|
||||||
alarmContactUuid:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
nullable: true
|
|
||||||
config:
|
config:
|
||||||
$ref: '#/components/schemas/HsHostingAssetConfiguration'
|
$ref: '#/components/schemas/HsHostingAssetConfiguration'
|
||||||
|
|
||||||
@ -78,10 +72,6 @@ components:
|
|||||||
minLength: 3
|
minLength: 3
|
||||||
maxLength: 80
|
maxLength: 80
|
||||||
nullable: false
|
nullable: false
|
||||||
alarmContactUuid:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
nullable: true
|
|
||||||
config:
|
config:
|
||||||
$ref: '#/components/schemas/HsHostingAssetConfiguration'
|
$ref: '#/components/schemas/HsHostingAssetConfiguration'
|
||||||
required:
|
required:
|
||||||
|
@ -58,7 +58,6 @@ public class ArchitectureTest {
|
|||||||
"..hs.booking.project",
|
"..hs.booking.project",
|
||||||
"..hs.booking.item",
|
"..hs.booking.item",
|
||||||
"..hs.booking.item.validators",
|
"..hs.booking.item.validators",
|
||||||
"..hs.hosting.contact",
|
|
||||||
"..hs.hosting.asset",
|
"..hs.hosting.asset",
|
||||||
"..hs.hosting.asset.validators",
|
"..hs.hosting.asset.validators",
|
||||||
"..errors",
|
"..errors",
|
||||||
@ -151,8 +150,7 @@ public class ArchitectureTest {
|
|||||||
.should().onlyBeAccessed().byClassesThat()
|
.should().onlyBeAccessed().byClassesThat()
|
||||||
.resideInAnyPackage(
|
.resideInAnyPackage(
|
||||||
"..hs.booking.(*)..",
|
"..hs.booking.(*)..",
|
||||||
"..hs.hosting.(*)..",
|
"..hs.hosting.(*).."
|
||||||
"..hs.validation" // TODO.impl: Some Validators need to be refactored to booking package.
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
|
@ -7,8 +7,6 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
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.hs.office.debitor.HsOfficeDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
|
||||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||||
@ -56,9 +54,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeDebitorRepository debitorRepo;
|
HsOfficeDebitorRepository debitorRepo;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
HsOfficeContactRepository contactRepo;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@ -430,7 +425,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset("2001", MANAGED_SERVER,
|
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));
|
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
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -438,14 +432,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"alarmContactUuid": "%s",
|
|
||||||
"config": {
|
"config": {
|
||||||
"monit_max_ssd_usage": 85,
|
"monit_max_ssd_usage": 85,
|
||||||
"monit_max_hdd_usage": null,
|
"monit_max_hdd_usage": null,
|
||||||
"monit_min_free_ssd": 5
|
"monit_min_free_ssd": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""".formatted(alarmContactUuid))
|
""")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.patch("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
.patch("http://localhost/api/hs/hosting/assets/" + givenAsset.getUuid())
|
||||||
@ -457,11 +450,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"identifier": "vm2001",
|
"identifier": "vm2001",
|
||||||
"caption": "some test-asset",
|
"caption": "some test-asset",
|
||||||
"alarmContact": {
|
|
||||||
"uuid": "%s",
|
|
||||||
"caption": "second contact",
|
|
||||||
"emailAddresses": { "main": "contact-admin@secondcontact.example.com" }
|
|
||||||
},
|
|
||||||
"config": {
|
"config": {
|
||||||
"monit_max_cpu_usage": 90,
|
"monit_max_cpu_usage": 90,
|
||||||
"monit_max_ram_usage": 70,
|
"monit_max_ram_usage": 70,
|
||||||
@ -469,15 +457,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"monit_min_free_ssd": 5
|
"monit_min_free_ssd": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""".formatted(alarmContactUuid)));
|
""")); // @formatter:on
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
// finally, the asset is actually updated
|
// finally, the asset is actually updated
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
|
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
|
||||||
.matches(asset -> {
|
.matches(asset -> {
|
||||||
assertThat(asset.getAlarmContact().toString()).isEqualTo(
|
|
||||||
"contact(caption='second contact', emailAddresses='{main=contact-admin@secondcontact.example.com}')");
|
|
||||||
assertThat(asset.getConfig().toString()).isEqualTo(
|
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 }");
|
"{ monit_max_cpu_usage: 90, monit_max_ram_usage: 70, monit_max_ssd_usage: 85, monit_min_free_ssd: 5 }");
|
||||||
return true;
|
return true;
|
||||||
@ -485,13 +470,6 @@ 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
|
@Nested
|
||||||
@Order(5)
|
@Order(5)
|
||||||
class DeleteAsset {
|
class DeleteAsset {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset;
|
package net.hostsharing.hsadminng.hs.hosting.asset;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.contact.HsHostingContactEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
|
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetPatchResource;
|
||||||
|
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||||
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
import net.hostsharing.hsadminng.mapper.KeyValueMap;
|
||||||
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
|
import net.hostsharing.hsadminng.rbac.test.PatchUnitTestBase;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
@ -31,7 +31,6 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
> {
|
> {
|
||||||
|
|
||||||
private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID();
|
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(
|
private static final Map<String, Object> INITIAL_CONFIG = patchMap(
|
||||||
entry("CPU", 1),
|
entry("CPU", 1),
|
||||||
@ -48,9 +47,6 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
entry("SSD", 256),
|
entry("SSD", 256),
|
||||||
entry("MEM", 64)
|
entry("MEM", 64)
|
||||||
);
|
);
|
||||||
final HsHostingContactEntity givenInitialContact = HsHostingContactEntity.builder()
|
|
||||||
.uuid(UUID.randomUUID())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
private static final String INITIAL_CAPTION = "initial caption";
|
private static final String INITIAL_CAPTION = "initial caption";
|
||||||
private static final String PATCHED_CAPTION = "patched caption";
|
private static final String PATCHED_CAPTION = "patched caption";
|
||||||
@ -60,12 +56,10 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void initMocks() {
|
void initMocks() {
|
||||||
// lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
|
lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
|
||||||
// HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
|
HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
|
||||||
lenient().when(em.getReference(eq(HsHostingAssetEntity.class), any())).thenAnswer(invocation ->
|
lenient().when(em.getReference(eq(HsHostingAssetEntity.class), any())).thenAnswer(invocation ->
|
||||||
HsHostingAssetEntity.builder().uuid(invocation.getArgument(1)).build());
|
HsHostingAssetEntity.builder().uuid(invocation.getArgument(1)).build());
|
||||||
lenient().when(em.getReference(eq(HsHostingContactEntity.class), any())).thenAnswer(invocation ->
|
|
||||||
HsHostingContactEntity.builder().uuid(invocation.getArgument(1)).build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -75,7 +69,6 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
entity.setBookingItem(TEST_BOOKING_ITEM);
|
entity.setBookingItem(TEST_BOOKING_ITEM);
|
||||||
entity.getConfig().putAll(KeyValueMap.from(INITIAL_CONFIG));
|
entity.getConfig().putAll(KeyValueMap.from(INITIAL_CONFIG));
|
||||||
entity.setCaption(INITIAL_CAPTION);
|
entity.setCaption(INITIAL_CAPTION);
|
||||||
entity.setAlarmContact(givenInitialContact);
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +79,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HsHostingAssetEntityPatcher createPatcher(final HsHostingAssetEntity server) {
|
protected HsHostingAssetEntityPatcher createPatcher(final HsHostingAssetEntity server) {
|
||||||
return new HsHostingAssetEntityPatcher(em, server);
|
return new HsHostingAssetEntityPatcher(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -103,18 +96,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
PATCH_CONFIG,
|
PATCH_CONFIG,
|
||||||
HsHostingAssetEntity::putConfig,
|
HsHostingAssetEntity::putConfig,
|
||||||
PATCHED_CONFIG)
|
PATCHED_CONFIG)
|
||||||
.notNullable(),
|
|
||||||
new JsonNullableProperty<>(
|
|
||||||
"alarmContact",
|
|
||||||
HsHostingAssetPatchResource::setAlarmContactUuid,
|
|
||||||
PATCHED_CONTACT_UUID,
|
|
||||||
HsHostingAssetEntity::setAlarmContact,
|
|
||||||
newContact(PATCHED_CONTACT_UUID))
|
|
||||||
.notNullable()
|
.notNullable()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HsHostingContactEntity newContact(final UUID uuid) {
|
|
||||||
return HsHostingContactEntity.builder().uuid(uuid).build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user