introduce EntityManager to HostingAssetEntitySaveProcessor

This commit is contained in:
Michael Hoennig 2024-07-29 15:40:58 +02:00
parent 20f154c145
commit 99a9358679
9 changed files with 34 additions and 18 deletions

View File

@ -72,7 +72,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final var entity = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER); final var entity = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var mapped = new HostingAssetEntitySaveProcessor(entity) final var mapped = new HostingAssetEntitySaveProcessor(em, entity)
.preprocessEntity() .preprocessEntity()
.validateEntity() .validateEntity()
.prepareForSave() .prepareForSave()
@ -133,7 +133,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
new HsHostingAssetEntityPatcher(em, entity).apply(body); new HsHostingAssetEntityPatcher(em, entity).apply(body);
final var mapped = new HostingAssetEntitySaveProcessor(entity) final var mapped = new HostingAssetEntitySaveProcessor(em, entity)
.preprocessEntity() .preprocessEntity()
.validateEntity() .validateEntity()
.prepareForSave() .prepareForSave()
@ -162,5 +162,5 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final BiConsumer<HsHostingAssetEntity, HsHostingAssetResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) final BiConsumer<HsHostingAssetEntity, HsHostingAssetResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource)
-> resource.setConfig(HostingAssetEntityValidatorRegistry.forType(entity.getType()) -> resource.setConfig(HostingAssetEntityValidatorRegistry.forType(entity.getType())
.revampProperties(entity, (Map<String, Object>) resource.getConfig())); .revampProperties(em, entity, (Map<String, Object>) resource.getConfig()));
} }

View File

@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource; import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator; import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import jakarta.persistence.EntityManager;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
@ -15,10 +16,12 @@ public class HostingAssetEntitySaveProcessor {
private final HsEntityValidator<HsHostingAssetEntity> validator; private final HsEntityValidator<HsHostingAssetEntity> validator;
private String expectedStep = "preprocessEntity"; private String expectedStep = "preprocessEntity";
private final EntityManager em;
private HsHostingAssetEntity entity; private HsHostingAssetEntity entity;
private HsHostingAssetResource resource; private HsHostingAssetResource resource;
public HostingAssetEntitySaveProcessor(final HsHostingAssetEntity entity) { public HostingAssetEntitySaveProcessor(final EntityManager em, final HsHostingAssetEntity entity) {
this.em = em;
this.entity = entity; this.entity = entity;
this.validator = HostingAssetEntityValidatorRegistry.forType(entity.getType()); this.validator = HostingAssetEntityValidatorRegistry.forType(entity.getType());
} }
@ -41,7 +44,7 @@ public class HostingAssetEntitySaveProcessor {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public HostingAssetEntitySaveProcessor prepareForSave() { public HostingAssetEntitySaveProcessor prepareForSave() {
step("prepareForSave", "saveUsing"); step("prepareForSave", "saveUsing");
validator.prepareProperties(entity); validator.prepareProperties(em, entity);
return this; return this;
} }
@ -70,7 +73,7 @@ public class HostingAssetEntitySaveProcessor {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public HsHostingAssetResource revampProperties() { public HsHostingAssetResource revampProperties() {
step("revampProperties", null); step("revampProperties", null);
final var revampedProps = validator.revampProperties(entity, (Map<String, Object>) resource.getConfig()); final var revampedProps = validator.revampProperties(em, entity, (Map<String, Object>) resource.getConfig());
resource.setConfig(revampedProps); resource.setConfig(revampedProps);
return resource; return resource;
} }

View File

@ -2,6 +2,7 @@ package net.hostsharing.hsadminng.hs.validation;
import jakarta.persistence.EntityManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@ -106,21 +107,21 @@ public abstract class HsEntityValidator<E extends PropertiesProvider> {
throw new IllegalArgumentException("Integer value (or null) expected, but got " + value); throw new IllegalArgumentException("Integer value (or null) expected, but got " + value);
} }
public void prepareProperties(final E entity) { public void prepareProperties(final EntityManager em, final E entity) {
stream(propertyValidators).forEach(p -> { stream(propertyValidators).forEach(p -> {
if ( p.isWriteOnly() && p.isComputed()) { if ( p.isWriteOnly() && p.isComputed()) {
entity.directProps().put(p.propertyName, p.compute(entity)); entity.directProps().put(p.propertyName, p.compute(em, entity));
} }
}); });
} }
public Map<String, Object> revampProperties(final E entity, final Map<String, Object> config) { public Map<String, Object> revampProperties(final EntityManager em, final E entity, final Map<String, Object> config) {
final var copy = new HashMap<>(config); final var copy = new HashMap<>(config);
stream(propertyValidators).forEach(p -> { stream(propertyValidators).forEach(p -> {
if (p.isWriteOnly()) { if (p.isWriteOnly()) {
copy.remove(p.propertyName); copy.remove(p.propertyName);
} else if (p.isReadOnly() && p.isComputed()) { } else if (p.isReadOnly() && p.isComputed()) {
copy.put(p.propertyName, p.compute(entity)); copy.put(p.propertyName, p.compute(em, entity));
} }
}); });
return copy; return copy;

View File

@ -9,6 +9,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.mapper.Array; import net.hostsharing.hsadminng.mapper.Array;
import org.apache.commons.lang3.function.TriFunction; import org.apache.commons.lang3.function.TriFunction;
import jakarta.persistence.EntityManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -307,7 +308,7 @@ protected void setDeferredInit(final Function<ValidatableProperty<?, ?>[], T[]>
return self(); return self();
} }
public <E extends PropertiesProvider> T compute(final E entity) { public <E extends PropertiesProvider> T compute(final EntityManager em, final E entity) {
return computedBy.apply(entity); return computedBy.apply(entity);
} }

View File

@ -4,6 +4,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import java.util.HashMap; import java.util.HashMap;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -24,6 +25,8 @@ class HsMariaDbUserHostingAssetValidatorUnitTest {
.caption("some valid test MariaDB-Instance") .caption("some valid test MariaDB-Instance")
.build(); .build();
private EntityManager em = null; // not actually needed in these test cases
private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() { private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() {
return HsHostingAssetEntity.builder() return HsHostingAssetEntity.builder()
.type(MARIADB_USER) .type(MARIADB_USER)
@ -58,7 +61,7 @@ class HsMariaDbUserHostingAssetValidatorUnitTest {
// when // when
// HashGenerator.nextSalt("Ly3LbsArtL5u4EVt"); // not needed for mysql_native_password // HashGenerator.nextSalt("Ly3LbsArtL5u4EVt"); // not needed for mysql_native_password
validator.prepareProperties(givenMariaDbUserHostingAsset); validator.prepareProperties(em, givenMariaDbUserHostingAsset);
// then // then
assertThat(givenMariaDbUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries( assertThat(givenMariaDbUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries(

View File

@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
@ -27,6 +28,8 @@ class HsPostgreSqlUserHostingAssetValidatorUnitTest {
.caption("some valid test PgSql-Instance") .caption("some valid test PgSql-Instance")
.build(); .build();
private EntityManager em = null; // not actually needed in these test cases
private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() { private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() {
return HsHostingAssetEntity.builder() return HsHostingAssetEntity.builder()
.type(PGSQL_USER) .type(PGSQL_USER)
@ -61,7 +64,7 @@ class HsPostgreSqlUserHostingAssetValidatorUnitTest {
// when // when
HashGenerator.nextSalt(new String(Base64.getDecoder().decode("L1QxSVNyTU81b3NZS1djNg=="), Charset.forName("latin1"))); HashGenerator.nextSalt(new String(Base64.getDecoder().decode("L1QxSVNyTU81b3NZS1djNg=="), Charset.forName("latin1")));
validator.prepareProperties(givenMariaDbUserHostingAsset); validator.prepareProperties(em, givenMariaDbUserHostingAsset);
// then // then
assertThat(givenMariaDbUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries( assertThat(givenMariaDbUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries(

View File

@ -5,6 +5,7 @@ import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import java.util.HashMap; import java.util.HashMap;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -43,6 +44,8 @@ class HsUnixUserHostingAssetValidatorUnitTest {
))) )))
.build(); .build();
private EntityManager em = null; // not actually needed in these test cases
@Test @Test
void preparesUnixUser() { void preparesUnixUser() {
// given // given
@ -51,7 +54,7 @@ class HsUnixUserHostingAssetValidatorUnitTest {
// when // when
HashGenerator.nextSalt("Ly3LbsArtL5u4EVt"); HashGenerator.nextSalt("Ly3LbsArtL5u4EVt");
validator.prepareProperties(unixUserHostingAsset); validator.prepareProperties(em, unixUserHostingAsset);
// then // then
assertThat(unixUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries( assertThat(unixUserHostingAsset.getConfig()).containsExactlyInAnyOrderEntriesOf(ofEntries(
@ -142,7 +145,7 @@ class HsUnixUserHostingAssetValidatorUnitTest {
// when // when
HashGenerator.nextSalt("Ly3LbsArtL5u4EVt"); HashGenerator.nextSalt("Ly3LbsArtL5u4EVt");
final var result = validator.revampProperties(unixUserHostingAsset, unixUserHostingAsset.getConfig()); final var result = validator.revampProperties(em, unixUserHostingAsset, unixUserHostingAsset.getConfig());
// then // then
assertThat(result).containsExactlyInAnyOrderEntriesOf(ofEntries( assertThat(result).containsExactlyInAnyOrderEntriesOf(ofEntries(

View File

@ -352,7 +352,7 @@ public class ImportHostingAssets extends ImportOfficeData {
void validateHostingAssets() { void validateHostingAssets() {
hostingAssets.forEach((id, ha) -> { hostingAssets.forEach((id, ha) -> {
try { try {
new HostingAssetEntitySaveProcessor(ha) new HostingAssetEntitySaveProcessor(em, ha)
.preprocessEntity() .preprocessEntity()
.validateEntity(); .validateEntity();
} catch (final Exception exc) { } catch (final Exception exc) {
@ -408,7 +408,7 @@ public class ImportHostingAssets extends ImportOfficeData {
context(rbacSuperuser); context(rbacSuperuser);
hostingAssets.forEach((key, ha) -> { hostingAssets.forEach((key, ha) -> {
if (ha.getType() == hsHostingAssetType) { if (ha.getType() == hsHostingAssetType) {
new HostingAssetEntitySaveProcessor(ha) new HostingAssetEntitySaveProcessor(em, ha)
.preprocessEntity() .preprocessEntity()
.validateEntity() .validateEntity()
.prepareForSave() .prepareForSave()

View File

@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.ValueSource;
import jakarta.persistence.EntityManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -19,6 +20,7 @@ class PasswordPropertyUnitTest {
private final ValidatableProperty<PasswordProperty, String> passwordProp = private final ValidatableProperty<PasswordProperty, String> passwordProp =
passwordProperty("password").minLength(8).maxLength(40).hashedUsing(LINUX_SHA512).writeOnly(); passwordProperty("password").minLength(8).maxLength(40).hashedUsing(LINUX_SHA512).writeOnly();
private final List<String> violations = new ArrayList<>(); private final List<String> violations = new ArrayList<>();
private EntityManager em = null; // not actually needed in these test cases
@ParameterizedTest @ParameterizedTest
@ValueSource(strings = { @ValueSource(strings = {
@ -99,7 +101,7 @@ class PasswordPropertyUnitTest {
void shouldComputeHash() { void shouldComputeHash() {
// when // when
final var result = passwordProp.compute(new PropertiesProvider() { final var result = passwordProp.compute(em, new PropertiesProvider() {
@Override @Override
public Map<String, Object> directProps() { public Map<String, Object> directProps() {