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 6421aa1d..f1093311 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 @@ -16,6 +16,7 @@ import java.net.IDN; import java.util.List; import java.util.function.Function; +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; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SMTP_SETUP; @@ -43,6 +44,7 @@ public class DomainSetupHostingAssetFactory extends HostingAssetFactory { final var assignedToUnixUserAsset = domainHttpSetupAsset.getAssignedToAsset(); // TODO.legacy: don't create DNS setup as long as we need to remain support legacy web-ui etc. + assertDomainDnsSetupAssetNotSupplied(domainSetupAsset); createDomainSubSetupAssetEntity( domainSetupAsset, @@ -96,6 +98,12 @@ public class DomainSetupHostingAssetFactory extends HostingAssetFactory { return domainHttpSetupAsset; } + private void assertDomainDnsSetupAssetNotSupplied(final HsHostingAssetRealEntity domainSetupAsset) { + if (getSubHostingAssetResources().stream().anyMatch(ha -> ha.getType() == DOMAIN_DNS_SETUP)) { + throw new ValidationException("domain DNS setup not allowed for legacy compatibility"); + } + } + private void createDomainSubSetupAssetEntity( final HsHostingAssetRealEntity domainSetupAsset, final HsHostingAssetType subAssetType, diff --git a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java index cf30a5b0..83984bb0 100644 --- a/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java +++ b/src/main/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HostingAssetFactory.java @@ -21,8 +21,8 @@ abstract class HostingAssetFactory { protected abstract HsHostingAsset create(); public String performSaveProcess() { - final var newHostingAsset = create(); try { + final var newHostingAsset = create(); persist(newHostingAsset); return null; } catch (final Exception e) { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListenerUnitTest.java b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java similarity index 64% rename from src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListenerUnitTest.java rename to src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java index 8ae27c5a..9220f509 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/HsBookingItemCreatedListenerUnitTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/hosting/asset/factories/DomainSetupHostingAssetFactoryUnitTest.java @@ -26,8 +26,9 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX import static net.hostsharing.hsadminng.mapper.PatchableMapWrapper.entry; import static org.assertj.core.api.Assertions.assertThat; +// Tests the DomainSetupHostingAssetFactory through a HsBookingItemCreatedListener instance. @ExtendWith(MockitoExtension.class) -class HsBookingItemCreatedListenerUnitTest { +class DomainSetupHostingAssetFactoryUnitTest { private final HsHostingAssetRealEntity managedWebspaceHostingAsset = HsHostingAssetRealEntity.builder() .uuid(UUID.randomUUID()) @@ -63,13 +64,10 @@ class HsBookingItemCreatedListenerUnitTest { @Test void doesNotPersistEventEntityWithoutValidationErrors() { // given - final var givenBookingItem = HsBookingItemRealEntity.builder() - .type(HsBookingItemType.DOMAIN_SETUP) - .resources(Map.ofEntries( - entry("domainName", "example.org"), - entry("verificationCode", "just-a-fake-verification-code") - )) - .build(); + 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 @@ -96,14 +94,11 @@ class HsBookingItemCreatedListenerUnitTest { } @Test - void persistsEventEntityIfHostingAssetVerificationFails() { + void persistsEventEntityIfDomainSetupVerificationFails() { // given - final var givenBookingItem = HsBookingItemRealEntity.builder() - .type(HsBookingItemType.DOMAIN_SETUP) - .resources(Map.ofEntries( - entry("domainName", "example.org") - )) - .build(); + final var givenBookingItem = createBookingItemFromResources( + entry("domainName", "example.org") + ); final var givenAssetJson = """ { "identifier": "example.org", // also as default for all subAssets @@ -130,8 +125,61 @@ class HsBookingItemCreatedListenerUnitTest { assertThat(eventEntity.getBookingItem()).isSameAs(givenBookingItem); assertThat(eventEntity.getAssetJson()).isEqualTo(givenAssetJson); assertThat(eventEntity.getStatusMessage()).isEqualTo( - "[[DNS] no TXT record 'Hostsharing-domain-setup-verification-code=null' found for domain name 'example.org' (nor in its super-domain)]"); + "[[DNS] no TXT record 'Hostsharing-domain-setup-verification-code=null' found for domain name 'example.org' (nor in its super-domain)]" + ); return true; }); } + + @Test + void persistsEventEntityIfDomainDnsSetupIsSupplied() { + // 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_DNS_SETUP", + "assignedToAssetUuid": "{managedWebspaceHostingAssetUuid}" + } + ] + } + """ + .replace("{unixUserHostingAssetUuid}", unixUserHostingAsset.getUuid().toString()) + .replace("{managedWebspaceHostingAssetUuid}", managedWebspaceHostingAsset.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 + emwFake.stream(BookingItemCreatedEventEntity.class) + .reduce(EntityManagerWrapperFake::toSingleElement) + .map(eventEntity -> { + assertThat(eventEntity.getBookingItem()).isSameAs(givenBookingItem); + assertThat(eventEntity.getAssetJson()).isEqualTo(givenAssetJson); + assertThat(eventEntity.getStatusMessage()).isEqualTo( + "domain DNS setup not allowed for legacy compatibility"); + return true; + }); + } + + @SafeVarargs + private static HsBookingItemRealEntity createBookingItemFromResources(final Map.Entry... givenResources) { + return HsBookingItemRealEntity.builder() + .type(HsBookingItemType.DOMAIN_SETUP) + .resources(Map.ofEntries(givenResources)) + .build(); + } }