From 7f066f8b6a3ee1f4310f10008f4bcc78ca187fb4 Mon Sep 17 00:00:00 2001 From: Michael Hoennig Date: Wed, 2 Oct 2024 16:37:54 +0200 Subject: [PATCH] WIP --- .../DomainSetupHostingAssetFactory.java | 36 ++++++++++--- .../hostsharing/hsadminng/lambda/Reducer.java | 8 +++ .../hs-hosting/hs-hosting-asset-schemas.yaml | 6 +-- ...HsBookingItemControllerAcceptanceTest.java | 45 +++++++++------- ...omainSetupHostingAssetFactoryUnitTest.java | 54 +++++++++++++++++-- .../persistence/EntityManagerWrapperFake.java | 4 -- 6 files changed, 115 insertions(+), 38 deletions(-) create mode 100644 src/main/java/net/hostsharing/hsadminng/lambda/Reducer.java diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java index f1093311..248d3bee 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactory.java @@ -8,14 +8,17 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity; +import net.hostsharing.hsadminng.lambda.Reducer; import net.hostsharing.hsadminng.mapper.StandardMapper; import net.hostsharing.hsadminng.persistence.EntityManagerWrapper; import jakarta.validation.ValidationException; import java.net.IDN; import java.util.List; +import java.util.Optional; import java.util.function.Function; +import static java.util.Optional.ofNullable; import static net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsHostingAssetTypeResource.DOMAIN_DNS_SETUP; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_HTTP_SETUP; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_MBOX_SETUP; @@ -109,14 +112,31 @@ public class DomainSetupHostingAssetFactory extends HostingAssetFactory { final HsHostingAssetType subAssetType, final Function, HsHostingAssetRealEntity.HsHostingAssetRealEntityBuilder> builderTransformer) { final var resourceType = HsHostingAssetTypeResource.valueOf(subAssetType.name()); - if (getSubHostingAssetResources().stream().noneMatch(ha -> ha.getType() == resourceType)) { - final var subAssetEntity = builderTransformer.apply( - HsHostingAssetRealEntity.builder() - .type(HsHostingAssetType.valueOf(subAssetType.name())) - .parentAsset(domainSetupAsset)) - .build(); - domainSetupAsset.getSubHostingAssets().add(subAssetEntity); - } + final var subAssetResource = getSubHostingAssetResources().stream() + .filter(ha -> ha.getType() == resourceType) + .reduce(Reducer::toSingleElement); + final var subAssetEntity = builderTransformer.apply( + HsHostingAssetRealEntity.builder() + .type(subAssetType) + .parentAsset(domainSetupAsset)) + .build(); + domainSetupAsset.getSubHostingAssets().add(subAssetEntity); + subAssetResource.ifPresent( + res -> { + ofNullable(res.getAssignedToAssetUuid()) + .map(uuid -> emw.find(HsHostingAssetRealEntity.class, uuid)) + .ifPresent(subAssetEntity::setAssignedToAsset); + ofNullable(res.getAlarmContactUuid()) + .map(uuid -> emw.find(HsOfficeContactRealEntity.class, uuid)) + .ifPresent(subAssetEntity::setAlarmContact); + ofNullable(res.getIdentifier()).ifPresent(subAssetEntity::setIdentifier); + ofNullable(res.getCaption()).ifPresent(subAssetEntity::setCaption); + res.getConfig(); + res.get + + + } + ); } private String getDomainName() { diff --git a/src/main/java/net/hostsharing/hsadminng/lambda/Reducer.java b/src/main/java/net/hostsharing/hsadminng/lambda/Reducer.java new file mode 100644 index 00000000..52b4df79 --- /dev/null +++ b/src/main/java/net/hostsharing/hsadminng/lambda/Reducer.java @@ -0,0 +1,8 @@ +package net.hostsharing.hsadminng.lambda; + +public class Reducer { + public static T toSingleElement(T last, T next) { + throw new AssertionError("only a single entity expected"); + } + +} diff --git a/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml b/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml index 9ab6cf07..44813162 100644 --- a/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml +++ b/src/main/resources/api-definition/hs-hosting/hs-hosting-asset-schemas.yaml @@ -135,9 +135,6 @@ components: HsHostingAssetSubInsert: type: object properties: - assignedToAssetUuid: - type: string - format: uuid type: $ref: '#/components/schemas/HsHostingAssetType' identifier: @@ -150,6 +147,9 @@ components: minLength: 3 maxLength: 80 nullable: false + assignedToAssetUuid: + type: string + format: uuid alarmContactUuid: type: string format: uuid diff --git a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java index 270e7917..15855fc9 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/booking/item/HsBookingItemControllerAcceptanceTest.java @@ -201,24 +201,33 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup .header("current-subject", "superuser-alex@hostsharing.net") .contentType(ContentType.JSON) .body(""" - { - "projectUuid": "{projectUuid}", - "type": "DOMAIN_SETUP", - "caption": "Domain-Setup for example.org", - "resources": { - "domainName": "example.org", - "verificationCode": "just-a-fake-verification-code" - }, - "asset": { // FIXME: rename to hostingAsset - "identifier": "example.org", // also as default for all subAssets - "subHostingAssets": [ - { - "type": "DOMAIN_HTTP_SETUP", - "assignedToAssetUuid": "{unixUserUuid}" - } - ] - } - } +{ + "projectUuid": "{projectUuid}", + "type": "DOMAIN_SETUP", + "caption": "Domain-Setup for example.org", + "resources": { + "domainName": "example.org", + "verificationCode": "just-a-fake-verification-code" + }, + "asset": { // FIXME: rename to hostingAsset + "identifier": "example.org", // also as default for all subAssets + "subHostingAssets": [ + { + "type": "DOMAIN_DNS_SETUP" + }, + { + "type": "DOMAIN_HTTP_SETUP", + "assignedToAssetUuid": "{unixUserUuid}" + }, + { + "type": "DOMAIN_MBOX_SETUP" + }, + { + "type": "DOMAIN_SMTP_SETUP" + } + ] + } +} """ .replace("{projectUuid}", givenProject.getUuid().toString()) .replace("{unixUserUuid}", givenUnixUser.getUuid().toString()) diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java index 5a846260..97c70952 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java @@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity; import net.hostsharing.hsadminng.hs.hosting.asset.validators.Dns; +import net.hostsharing.hsadminng.lambda.Reducer; import net.hostsharing.hsadminng.persistence.EntityManagerWrapperFake; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -33,14 +34,22 @@ class DomainSetupHostingAssetFactoryUnitTest { private final HsHostingAssetRealEntity managedWebspaceHostingAsset = HsHostingAssetRealEntity.builder() .uuid(UUID.randomUUID()) .type(MANAGED_WEBSPACE) + .identifier("one00") .build(); private final HsHostingAssetRealEntity unixUserHostingAsset = HsHostingAssetRealEntity.builder() .uuid(UUID.randomUUID()) .type(UNIX_USER) + .identifier("one00-web") .parentAsset(managedWebspaceHostingAsset) .build(); + private final HsHostingAssetRealEntity anotherManagedWebspaceHostingAsset = HsHostingAssetRealEntity.builder() + .uuid(UUID.randomUUID()) + .type(MANAGED_WEBSPACE) + .identifier("two00") + .build(); + private EntityManagerWrapperFake emwFake = new EntityManagerWrapperFake(); @Spy @@ -160,6 +169,43 @@ class DomainSetupHostingAssetFactoryUnitTest { "domain DNS setup not allowed for legacy compatibility"); } + @Test + void persistsEventEntityIfSuppliedDomainUnixUserAndSmtpSetupWebspaceDontMatch() { + // given + final var givenBookingItem = createBookingItemFromResources( + entry("domainName", "example.org"), + entry("verificationCode", "just-a-fake-verification-code") + ); + final var givenAssetJson = """ + { + "identifier": "example.org", // also as default for all subAssets + "subHostingAssets": [ + { + "type": "DOMAIN_HTTP_SETUP", + "assignedToAssetUuid": "{unixUserHostingAssetUuid}" + }, + { + "type": "DOMAIN_SMTP_SETUP", + "assignedToAssetUuid": "{managedWebspaceHostingAssetUuid}" + } + ] + } + """ + .replace("{unixUserHostingAssetUuid}", unixUserHostingAsset.getUuid().toString()) + .replace("{managedWebspaceHostingAssetUuid}", anotherManagedWebspaceHostingAsset.getUuid().toString()); + Dns.fakeResultForDomain("example.org", + Dns.Result.fromRecords("Hostsharing-domain-setup-verification-code=just-a-fake-verification-code")); + + // when + listener.onApplicationEvent( + new BookingItemCreatedAppEvent(this, givenBookingItem, givenAssetJson) + ); + + // then + assertEventStatus(givenBookingItem, givenAssetJson, + "domain DNS setup not allowed for legacy compatibility"); + } + @SafeVarargs private static HsBookingItemRealEntity createBookingItemFromResources(final Map.Entry... givenResources) { return HsBookingItemRealEntity.builder() @@ -171,15 +217,13 @@ class DomainSetupHostingAssetFactoryUnitTest { private void assertEventStatus( final HsBookingItemRealEntity givenBookingItem, final String givenAssetJson, - final String expected) { + final String expectedErrorMessage) { emwFake.stream(BookingItemCreatedEventEntity.class) - .reduce(EntityManagerWrapperFake::toSingleElement) + .reduce(Reducer::toSingleElement) .map(eventEntity -> { assertThat(eventEntity.getBookingItem()).isSameAs(givenBookingItem); assertThat(eventEntity.getAssetJson()).isEqualTo(givenAssetJson); - assertThat(eventEntity.getStatusMessage()).isEqualTo( - expected - ); + assertThat(eventEntity.getStatusMessage()).isEqualTo(expectedErrorMessage); return true; }); } diff --git a/src/test/java/net/hostsharing/hsadminng/persistence/EntityManagerWrapperFake.java b/src/test/java/net/hostsharing/hsadminng/persistence/EntityManagerWrapperFake.java index fd05c371..4644677a 100644 --- a/src/test/java/net/hostsharing/hsadminng/persistence/EntityManagerWrapperFake.java +++ b/src/test/java/net/hostsharing/hsadminng/persistence/EntityManagerWrapperFake.java @@ -15,10 +15,6 @@ public class EntityManagerWrapperFake extends EntityManagerWrapper { private Map, Map> entityClasses = new HashMap<>(); - public static T toSingleElement(T last, T next) { - throw new AssertionError("only a single entity expected"); - } - @Override public boolean contains(final Object entity) { final var id = getEntityId(entity);