real rbac-entities in booking+hosting #89

Merged
hsh-michaelhoennig merged 15 commits from real-and-rbac-entities-everywhere into master 2024-08-21 06:18:38 +02:00
61 changed files with 581 additions and 399 deletions
Showing only changes of commit 7d4bdca454 - Show all commits

View File

@ -9,13 +9,11 @@ import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
@ -23,7 +21,6 @@ import org.hibernate.annotations.Type;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
@ -31,14 +28,12 @@ import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.PostLoad;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull;
import java.io.IOException;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
@ -50,36 +45,22 @@ import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.lowerInclusiveFromPostgresDateRange;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.upperInclusiveFromPostgresDateRange;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Builder(toBuilder = true)
@Table(name = "hs_booking_item_rv")
@MappedSuperclass
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingItemEntity>, PropertiesProvider {
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder(builderMethodName = "baseBuilder", toBuilder = true)
public abstract class HsBookingItem implements Stringifyable, BaseEntity<HsBookingItem>, PropertiesProvider {
private static Stringify<HsBookingItemEntity> stringify = stringify(HsBookingItemEntity.class)
.withProp(HsBookingItemEntity::getType)
.withProp(HsBookingItemEntity::getCaption)
.withProp(HsBookingItemEntity::getProject)
private static Stringify<HsBookingItem> stringify = stringify(HsBookingItem.class)
.withProp(HsBookingItem::getType)
.withProp(HsBookingItem::getCaption)
.withProp(HsBookingItem::getProject)
.withProp(e -> e.getValidity().asString())
.withProp(HsBookingItemEntity::getResources)
.withProp(HsBookingItem::getResources)
.quotedValues(false);
@Id
@ -95,7 +76,7 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentitemuuid")
private HsBookingItemEntity parentItem;
private HsBookingItemRealEntity parentItem;
@NotNull
@Column(name = "type")
@ -117,11 +98,23 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
private Map<String, Object> resources = new HashMap<>();
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true)
@JoinColumn(name="parentitemuuid", referencedColumnName="uuid")
private List<HsBookingItemEntity> subBookingItems;
@JoinColumn(name = "parentitemuuid", referencedColumnName = "uuid")
private List<HsBookingItemRealEntity> subBookingItems;
@OneToOne(mappedBy="bookingItem")
private HsHostingAssetRealEntity relatedHostingAsset;
// FIXME
// @OneToOne(targetEntity = HsHostingAssetRealEntity.class, mappedBy="bookingItem") // does not work in case of subclass HsBookingItemRbacEntity
// // because that bookingItem refers to a HsBookingItemRealEntity, not ...Rbac...
// @OneToOne(fetch = FetchType.LAZY)
// @JoinFormula(
// referencedColumnName = "uuid",
// value = """
// (
// SELECT DISTINCT asset.uuid
// FROM hs_hosting_asset asset
// WHERE asset.uuid=uuid
// )
// """)
// private HsHostingAssetRealEntity relatedHostingAsset;
@Transient
private PatchableMapWrapper<Object> resourcesWrapper;
@ -135,7 +128,7 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
}
public PatchableMapWrapper<Object> getResources() {
return PatchableMapWrapper.of(resourcesWrapper, (newWrapper) -> {resourcesWrapper = newWrapper; }, resources );
return PatchableMapWrapper.of(resourcesWrapper, (newWrapper) -> {resourcesWrapper = newWrapper;}, resources);
}
public void putResources(Map<String, Object> newResources) {
@ -166,10 +159,10 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
@Override
public Object getContextValue(final String propName) {
final var v = resources.get(propName);
if (v!= null) {
if (v != null) {
return v;
}
if (parentItem!=null) {
if (parentItem != null) {
return parentItem.getResources().get(propName);
}
return emptyMap();
@ -182,61 +175,13 @@ public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingI
@Override
public String toShortString() {
return ofNullable(relatedProject()).map(HsBookingProject::toShortString).orElse("D-???????-?") +
return ofNullable(getRelatedProject()).map(HsBookingProject::toShortString).orElse("D-???????-?") +
":" + caption;
}
private HsBookingProject relatedProject() {
if (project != null) {
return project;
}
return parentItem == null ? null : parentItem.relatedProject();
}
public HsBookingProject getRelatedProject() {
return project != null ? project
: parentItem != null ? parentItem.getRelatedProject()
: null; // can be the case for technical assets like IP-numbers
}
public static RbacView rbac() {
return rbacViewFor("bookingItem", HsBookingItemEntity.class)
.withIdentityView(SQL.projection("caption"))
.withRestrictedViewOrderBy(SQL.expression("validity"))
.withUpdatableColumns("version", "caption", "validity", "resources")
.toRole("global", ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.toRole("global", ADMIN).grantPermission(DELETE)
.importEntityAlias("project", HsBookingProject.class, usingDefaultCase(),
dependsOnColumn("projectUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
.toRole("project", ADMIN).grantPermission(INSERT)
.importEntityAlias("parentItem", HsBookingItemEntity.class, usingDefaultCase(),
dependsOnColumn("parentItemUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
.toRole("parentItem", ADMIN).grantPermission(INSERT)
.createRole(OWNER, (with) -> {
with.incomingSuperRole("project", AGENT);
with.incomingSuperRole("parentItem", AGENT);
})
.createSubRole(ADMIN, (with) -> {
with.permission(UPDATE);
})
.createSubRole(AGENT)
.createSubRole(TENANT, (with) -> {
with.outgoingSubRole("project", TENANT);
with.outgoingSubRole("parentItem", TENANT);
with.permission(SELECT);
})
.limitDiagramTo("bookingItem", "project", "global");
}
public static void main(String[] args) throws IOException {
rbac().generateWithBaseFileName("6-hs-booking/630-booking-item/6303-hs-booking-item-rbac");
}
}

View File

@ -33,7 +33,7 @@ public class HsBookingItemController implements HsBookingItemsApi {
private Mapper mapper;
@Autowired
private HsBookingItemRepository bookingItemRepo;
private HsBookingItemRbacRepository bookingItemRepo;
@PersistenceContext
private EntityManager em;
@ -61,9 +61,9 @@ public class HsBookingItemController implements HsBookingItemsApi {
context.define(currentUser, assumedRoles);
final var entityToSave = mapper.map(body, HsBookingItemEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var entityToSave = mapper.map(body, HsBookingItemRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var saved = HsBookingItemEntityValidatorRegistry.validated(bookingItemRepo.save(entityToSave));
final var saved = HsBookingItemEntityValidatorRegistry.validated(em, bookingItemRepo.save(entityToSave));
final var uri =
MvcUriComponentsBuilder.fromController(getClass())
@ -119,19 +119,19 @@ public class HsBookingItemController implements HsBookingItemsApi {
new HsBookingItemEntityPatcher(current).apply(body);
final var saved = bookingItemRepo.save(HsBookingItemEntityValidatorRegistry.validated(current));
final var saved = bookingItemRepo.save(HsBookingItemEntityValidatorRegistry.validated(em, current));
final var mapped = mapper.map(saved, HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(mapped);
}
final BiConsumer<HsBookingItemEntity, HsBookingItemResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
final BiConsumer<HsBookingItemRbacEntity, HsBookingItemResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource) -> {
resource.setValidFrom(entity.getValidity().lower());
if (entity.getValidity().hasUpperBound()) {
resource.setValidTo(entity.getValidity().upper().minusDays(1));
}
};
final BiConsumer<HsBookingItemInsertResource, HsBookingItemEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
final BiConsumer<HsBookingItemInsertResource, HsBookingItemRbacEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
entity.setValidity(toPostgresDateRange(LocalDate.now(), resource.getValidTo()));
entity.putResources(KeyValueMap.from(resource.getResources()));
};

View File

@ -10,9 +10,9 @@ import java.util.Optional;
public class HsBookingItemEntityPatcher implements EntityPatcher<HsBookingItemPatchResource> {
private final HsBookingItemEntity entity;
private final HsBookingItem entity;
public HsBookingItemEntityPatcher(final HsBookingItemEntity entity) {
public HsBookingItemEntityPatcher(final HsBookingItem entity) {
this.entity = entity;
}

View File

@ -0,0 +1,83 @@
package net.hostsharing.hsadminng.hs.booking.item;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import java.io.IOException;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.DELETE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.INSERT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.SELECT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Permission.UPDATE;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.ADMIN;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.AGENT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.OWNER;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Role.TENANT;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_booking_item_rv")
@SuperBuilder(toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
@AttributeOverrides({
@AttributeOverride(name = "uuid", column = @Column(name = "uuid"))
})
public class HsBookingItemRbacEntity extends HsBookingItem {
public static RbacView rbac() {
return rbacViewFor("bookingItem", HsBookingItemRbacEntity.class)
.withIdentityView(SQL.projection("caption"))
.withRestrictedViewOrderBy(SQL.expression("validity"))
.withUpdatableColumns("version", "caption", "validity", "resources")
.toRole("global", ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.toRole("global", ADMIN).grantPermission(DELETE)
.importEntityAlias("project", HsBookingProject.class, usingDefaultCase(),
dependsOnColumn("projectUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
.toRole("project", ADMIN).grantPermission(INSERT)
.importEntityAlias("parentItem", HsBookingItemRbacEntity.class, usingDefaultCase(),
dependsOnColumn("parentItemUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
.toRole("parentItem", ADMIN).grantPermission(INSERT)
.createRole(OWNER, (with) -> {
with.incomingSuperRole("project", AGENT);
with.incomingSuperRole("parentItem", AGENT);
})
.createSubRole(ADMIN, (with) -> {
with.permission(UPDATE);
})
.createSubRole(AGENT)
.createSubRole(TENANT, (with) -> {
with.outgoingSubRole("project", TENANT);
with.outgoingSubRole("parentItem", TENANT);
with.permission(SELECT);
})
.limitDiagramTo("bookingItem", "project", "global");
}
public static void main(String[] args) throws IOException {
rbac().generateWithBaseFileName("6-hs-booking/630-booking-item/6303-hs-booking-item-rbac");
}
}

View File

@ -0,0 +1,23 @@
package net.hostsharing.hsadminng.hs.booking.item;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingItemRbacRepository extends HsBookingItemRepository<HsBookingItemRbacEntity>,
Repository<HsBookingItemRbacEntity, UUID> {
Optional<HsBookingItemRbacEntity> findByUuid(final UUID bookingItemUuid);
List<HsBookingItemRbacEntity> findByCaption(String bookingItemCaption);
List<HsBookingItemRbacEntity> findAllByProjectUuid(final UUID projectItemUuid);
HsBookingItemRbacEntity save(HsBookingItemRbacEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -0,0 +1,24 @@
package net.hostsharing.hsadminng.hs.booking.item;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Table(name = "hs_booking_item")
@SuperBuilder(toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
@AttributeOverrides({
@AttributeOverride(name = "uuid", column = @Column(name = "uuid"))
})public class HsBookingItemRealEntity extends HsBookingItem {
}

View File

@ -0,0 +1,23 @@
package net.hostsharing.hsadminng.hs.booking.item;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingItemRealRepository extends HsBookingItemRepository<HsBookingItemRealEntity>,
Repository<HsBookingItemRealEntity, UUID> {
Optional<HsBookingItemRealEntity> findByUuid(final UUID bookingItemUuid);
List<HsBookingItemRealEntity> findByCaption(String bookingItemCaption);
List<HsBookingItemRealEntity> findAllByProjectUuid(final UUID projectItemUuid);
HsBookingItemRealEntity save(HsBookingItemRealEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -1,20 +1,18 @@
package net.hostsharing.hsadminng.hs.booking.item;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingItemRepository extends Repository<HsBookingItemEntity, UUID> {
public interface HsBookingItemRepository<E extends HsBookingItem> {
Optional<HsBookingItemEntity> findByUuid(final UUID bookingItemUuid);
Optional<E> findByUuid(final UUID bookingItemUuid);
List<HsBookingItemEntity> findByCaption(String bookingItemCaption);
List<E> findByCaption(String bookingItemCaption);
List<HsBookingItemEntity> findAllByProjectUuid(final UUID projectItemUuid);
List<E> findAllByProjectUuid(final UUID projectItemUuid);
HsBookingItemEntity save(HsBookingItemEntity current);
E save(E current);
int deleteByUuid(final UUID uuid);

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.hs.validation.ValidatableProperty;
import org.apache.commons.lang3.BooleanUtils;
@ -14,14 +14,14 @@ import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
import static java.util.Optional.ofNullable;
public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingItemEntity> {
public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingItem> {
public HsBookingItemEntityValidator(final ValidatableProperty<?, ?>... properties) {
super(properties);
}
@Override
public List<String> validateEntity(final HsBookingItemEntity bookingItem) {
public List<String> validateEntity(final HsBookingItem bookingItem) {
// TODO.impl: HsBookingItemType could do this similar to HsHostingAssetType
if ( bookingItem.getParentItem() == null && bookingItem.getProject() == null) {
return List.of(bookingItem + ".'parentItem' or .'project' expected to be set, but both are null");
@ -30,21 +30,21 @@ public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingIte
}
@Override
public List<String> validateContext(final HsBookingItemEntity bookingItem) {
public List<String> validateContext(final HsBookingItem bookingItem) {
return sequentiallyValidate(
() -> optionallyValidate(bookingItem.getParentItem()),
() -> validateAgainstSubEntities(bookingItem)
);
}
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
private static List<String> optionallyValidate(final HsBookingItem bookingItem) {
return bookingItem != null
? enrich(prefix(bookingItem.toShortString(), ""),
HsBookingItemEntityValidatorRegistry.forType(bookingItem.getType()).validateContext(bookingItem))
: emptyList();
}
protected List<String> validateAgainstSubEntities(final HsBookingItemEntity bookingItem) {
protected List<String> validateAgainstSubEntities(final HsBookingItem bookingItem) {
return enrich(prefix(bookingItem.toShortString(), "resources"),
Stream.concat(
stream(propertyValidators)
@ -58,7 +58,7 @@ public class HsBookingItemEntityValidator extends HsEntityValidator<HsBookingIte
// TODO.refa: convert into generic shape like multi-options validator
private static String validateMaxTotalValue(
final HsBookingItemEntity bookingItem,
final HsBookingItem bookingItem,
final ValidatableProperty<?, ?> propDef) {
final var propName = propDef.propertyName();
final var propUnit = ofNullable(propDef.unit()).map(u -> " " + u).orElse("");

View File

@ -1,10 +1,11 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.errors.MultiValidationException;
import jakarta.persistence.EntityManager;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -18,7 +19,7 @@ import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVAT
public class HsBookingItemEntityValidatorRegistry {
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItemEntity>> validators = new HashMap<>();
private static final Map<Enum<HsBookingItemType>, HsEntityValidator<HsBookingItem>> validators = new HashMap<>();
static {
register(PRIVATE_CLOUD, new HsPrivateCloudBookingItemValidator());
register(CLOUD_SERVER, new HsCloudServerBookingItemValidator());
@ -26,14 +27,14 @@ public class HsBookingItemEntityValidatorRegistry {
register(MANAGED_WEBSPACE, new HsManagedWebspaceBookingItemValidator());
}
private static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItemEntity> validator) {
private static void register(final Enum<HsBookingItemType> type, final HsEntityValidator<HsBookingItem> validator) {
stream(validator.propertyValidators).forEach( entry -> {
entry.verifyConsistency(Map.entry(type, validator));
});
validators.put(type, validator);
}
public static HsEntityValidator<HsBookingItemEntity> forType(final Enum<HsBookingItemType> type) {
public static HsEntityValidator<HsBookingItem> forType(final Enum<HsBookingItemType> type) {
if ( validators.containsKey(type)) {
return validators.get(type);
}
@ -44,14 +45,16 @@ public class HsBookingItemEntityValidatorRegistry {
return validators.keySet();
}
public static List<String> doValidate(final HsBookingItemEntity bookingItem) {
return HsEntityValidator.sequentiallyValidate(
() -> HsBookingItemEntityValidatorRegistry.forType(bookingItem.getType()).validateEntity(bookingItem),
() -> HsBookingItemEntityValidatorRegistry.forType(bookingItem.getType()).validateContext(bookingItem));
public static List<String> doValidate(final EntityManager em, final HsBookingItem bookingItem) {
return HsEntityValidator.doWithEntityManager(em, () ->
HsEntityValidator.sequentiallyValidate(
() -> HsBookingItemEntityValidatorRegistry.forType(bookingItem.getType()).validateEntity(bookingItem),
() -> HsBookingItemEntityValidatorRegistry.forType(bookingItem.getType()).validateContext(bookingItem))
);
}
public static HsBookingItemEntity validated(final HsBookingItemEntity entityToSave) {
MultiValidationException.throwIfNotEmpty(doValidate(entityToSave));
public static <E extends HsBookingItem> E validated(final EntityManager em, final E entityToSave) {
MultiValidationException.throwIfNotEmpty(doValidate(em, entityToSave));
return entityToSave;
}
}

View File

@ -1,13 +1,15 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import net.hostsharing.hsadminng.hs.validation.IntegerProperty;
import org.apache.commons.lang3.function.TriFunction;
import java.util.List;
import java.util.Optional;
import static java.util.Collections.emptyList;
import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_MBOX_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ADDRESS;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_DATABASE;
@ -38,9 +40,9 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
);
}
private static TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> unixUsers() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset())
private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> unixUsers() {
return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream()
.filter(subAsset -> subAsset.getType() == UNIX_USER)
.count())
@ -53,9 +55,9 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
};
}
private static TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> databaseUsers() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var dbUserCount = ofNullable(entity.getRelatedHostingAsset())
private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> databaseUsers() {
return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var dbUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType() == PGSQL_USER || bi.getType() == MARIADB_USER )
.count())
@ -68,9 +70,9 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
};
}
private static TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> databases() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset())
private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> databases() {
return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType()==PGSQL_USER || bi.getType()==MARIADB_USER )
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
@ -85,9 +87,9 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
};
}
private static TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> eMailAddresses() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset())
private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> eMailAddresses() {
return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType() == DOMAIN_MBOX_SETUP)
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
@ -101,4 +103,13 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
return emptyList();
};
}
private static Optional<HsHostingAssetRealEntity> fetchRelatedBookingItem(final HsBookingItem entity) {
// FIXME: cache the result
return HsEntityValidator.localEntityManager.get().createQuery(
"SELECT asset FROM HsHostingAssetRealEntity asset WHERE asset.bookingItem.uuid=:bookingItemUuid",
HsHostingAssetRealEntity.class)
.setParameter("bookingItemUuid", entity.getUuid())
.getResultStream().findFirst(); // there are 0 or 1, never more
}
}

View File

@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder(builderMethodName = "baseBuilder", toBuilder = true)
public class HsBookingProject implements Stringifyable, BaseEntity<HsBookingProject> {
public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBookingProject> {
private static Stringify<HsBookingProject> stringify = stringify(HsBookingProject.class)
.withProp(HsBookingProject::getDebitor)

View File

@ -8,7 +8,8 @@ import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
@ -48,7 +49,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder(builderMethodName = "baseBuilder", toBuilder = true)
public class HsHostingAsset implements Stringifyable, BaseEntity<HsHostingAsset>, PropertiesProvider {
public abstract class HsHostingAsset implements Stringifyable, BaseEntity<HsHostingAsset>, PropertiesProvider {
static Stringify<HsHostingAsset> stringify = stringify(HsHostingAsset.class)
.withProp(HsHostingAsset::getType)
@ -69,7 +70,7 @@ public class HsHostingAsset implements Stringifyable, BaseEntity<HsHostingAsset>
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "bookingitemuuid")
private HsBookingItemEntity bookingItem;
private HsBookingItemRealEntity bookingItem;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentassetuuid")
@ -129,7 +130,7 @@ public class HsHostingAsset implements Stringifyable, BaseEntity<HsHostingAsset>
public HsBookingProject getRelatedProject() {
return Optional.ofNullable(getBookingItem())
.map(HsBookingItemEntity::getRelatedProject)
.map(HsBookingItem::getRelatedProject)
.orElseGet(() -> Optional.ofNullable(getParentAsset())
.map(HsHostingAsset::getRelatedProject)
.orElse(null));

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.api.HsHostingAssetsApi;
@ -39,13 +39,13 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
private Mapper mapper;
@Autowired
private HsHostingAssetRbacRepository assetRbacRepo;
private HsHostingAssetRbacRepository rbacAssetRepo;
@Autowired
private HsHostingAssetRealRepository assetRealRepo;
private HsHostingAssetRealRepository realAssetRepo;
@Autowired
private HsBookingItemRepository bookingItemRepo;
private HsBookingItemRealRepository relBookingItemRepo;
hsh-michaelhoennig marked this conversation as resolved Outdated

real

real
@Override
@Transactional(readOnly = true)
@ -57,7 +57,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final HsHostingAssetTypeResource type) {
context.define(currentUser, assumedRoles);
final var entities = assetRbacRepo.findAllByCriteria(debitorUuid, parentAssetUuid, HsHostingAssetType.of(type));
final var entities = rbacAssetRepo.findAllByCriteria(debitorUuid, parentAssetUuid, HsHostingAssetType.of(type));
final var resources = mapper.mapList(entities, HsHostingAssetResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(resources);
@ -79,7 +79,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
.preprocessEntity()
.validateEntity()
.prepareForSave()
.saveUsing(assetRbacRepo::save)
.saveUsing(rbacAssetRepo::save)
.validateContext()
.mapUsing(e -> mapper.map(e, HsHostingAssetResource.class))
.revampProperties();
@ -101,7 +101,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
context.define(currentUser, assumedRoles);
final var result = assetRbacRepo.findByUuid(assetUuid);
final var result = rbacAssetRepo.findByUuid(assetUuid);
return result
.map(assetEntity -> ResponseEntity.ok(
mapper.map(assetEntity, HsHostingAssetResource.class, ENTITY_TO_RESOURCE_POSTMAPPER)))
@ -116,7 +116,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final UUID assetUuid) {
context.define(currentUser, assumedRoles);
final var result = assetRbacRepo.deleteByUuid(assetUuid);
final var result = rbacAssetRepo.deleteByUuid(assetUuid);
return result == 0
? ResponseEntity.notFound().build()
: ResponseEntity.noContent().build();
@ -132,7 +132,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
context.define(currentUser, assumedRoles);
final var entity = assetRbacRepo.findByUuid(assetUuid).orElseThrow();
final var entity = rbacAssetRepo.findByUuid(assetUuid).orElseThrow();
new HsHostingAssetEntityPatcher(em, entity).apply(body);
@ -140,7 +140,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
.preprocessEntity()
.validateEntity()
.prepareForSave()
.saveUsing(assetRbacRepo::save)
.saveUsing(rbacAssetRepo::save)
.validateContext()
.mapUsing(e -> mapper.map(e, HsHostingAssetResource.class))
.revampProperties();
@ -151,12 +151,12 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final BiConsumer<HsHostingAssetInsertResource, HsHostingAssetRbacEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
entity.putConfig(KeyValueMap.from(resource.getConfig()));
if (resource.getBookingItemUuid() != null) {
entity.setBookingItem(bookingItemRepo.findByUuid(resource.getBookingItemUuid())
entity.setBookingItem(relBookingItemRepo.findByUuid(resource.getBookingItemUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] bookingItemUuid %s not found".formatted(
resource.getBookingItemUuid()))));
}
if (resource.getParentAssetUuid() != null) {
entity.setParentAsset(assetRealRepo.findByUuid(resource.getParentAssetUuid())
entity.setParentAsset(realAssetRepo.findByUuid(resource.getParentAssetUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] parentAssetUuid %s not found".formatted(
resource.getParentAssetUuid()))));
}

View File

@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -47,7 +47,7 @@ public class HsHostingAssetRbacEntity extends HsHostingAsset {
.withUpdatableColumns("version", "caption", "config", "assignedToAssetUuid", "alarmContactUuid")
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.importEntityAlias("bookingItem", HsBookingItemEntity.class, usingDefaultCase(),
.importEntityAlias("bookingItem", HsBookingItem.class, usingDefaultCase(),
dependsOnColumn("bookingItemUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)

View File

@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import lombok.AllArgsConstructor;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.item.Node;
@ -376,7 +376,7 @@ class EntityTypeRelation<E, T extends Node> {
return (Set<R>) result;
}
static EntityTypeRelation<HsBookingItemEntity, HsBookingItemType> requires(final HsBookingItemType bookingItemType) {
static EntityTypeRelation<HsBookingItem, HsBookingItemType> requires(final HsBookingItemType bookingItemType) {
return new EntityTypeRelation<>(
REQUIRED,
BOOKING_ITEM,

View File

@ -72,8 +72,10 @@ public class HostingAssetEntitySaveProcessor {
/// validates the entity within it's parent and child hierarchy (e.g. totals validators and other limits)
public HostingAssetEntitySaveProcessor validateContext() {
step("validateContext", "mapUsing");
MultiValidationException.throwIfNotEmpty(validator.validateContext(entity));
return this;
return HsEntityValidator.doWithEntityManager(em, () -> {
MultiValidationException.throwIfNotEmpty(validator.validateContext(entity));
return this;
});
}
/// maps entity to JSON resource representation

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
@ -27,7 +27,7 @@ public abstract class HostingAssetEntityValidator extends HsEntityValidator<HsHo
static final ValidatableProperty<?, ?>[] NO_EXTRA_PROPERTIES = new ValidatableProperty<?, ?>[0];
private final ReferenceValidator<HsBookingItemEntity, HsBookingItemType> bookingItemReferenceValidation;
private final ReferenceValidator<HsBookingItem, HsBookingItemType> bookingItemReferenceValidation;
private final ReferenceValidator<HsHostingAsset, HsHostingAssetType> parentAssetReferenceValidation;
private final ReferenceValidator<HsHostingAsset, HsHostingAssetType> assignedToAssetReferenceValidation;
private final HostingAssetEntityValidator.AlarmContact alarmContactValidation;
@ -41,7 +41,7 @@ public abstract class HostingAssetEntityValidator extends HsEntityValidator<HsHo
assetType.bookingItemPolicy(),
assetType.bookingItemTypes(),
HsHostingAsset::getBookingItem,
HsBookingItemEntity::getType);
HsBookingItem::getType);
this.parentAssetReferenceValidation = new ReferenceValidator<>(
assetType.parentAssetPolicy(),
assetType.parentAssetTypes(),
@ -104,7 +104,7 @@ public abstract class HostingAssetEntityValidator extends HsEntityValidator<HsHo
: emptyList();
}
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) {
private static List<String> optionallyValidate(final HsBookingItem bookingItem) {
return bookingItem != null
? enrich(
prefix(bookingItem.toShortString(), "bookingItem"),

View File

@ -3,7 +3,6 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.hosting.generated.api.v1.model.HsHostingAssetResource;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import java.util.*;
@ -54,13 +53,4 @@ public class HostingAssetEntityValidatorRegistry {
public static Set<Enum<HsHostingAssetType>> types() {
return validators.keySet();
}
@SuppressWarnings("unchecked")
private static Map<String, Object> asMap(final HsHostingAssetResource resource) {
if (resource.getConfig() instanceof Map map) {
return map;
}
throw new IllegalArgumentException("expected a Map, but got a " + resource.getConfig().getClass());
}
}

View File

@ -21,6 +21,8 @@ import static net.hostsharing.hsadminng.hs.validation.ValidatableProperty.Comput
// TODO.refa: rename to HsEntityProcessor, also subclasses
public abstract class HsEntityValidator<E extends PropertiesProvider> {
public static final ThreadLocal<EntityManager> localEntityManager = new ThreadLocal<>();
public final ValidatableProperty<?, ?>[] propertyValidators;
public <T extends Enum <T>> HsEntityValidator(final ValidatableProperty<?, ?>... validators) {
@ -39,6 +41,16 @@ public abstract class HsEntityValidator<E extends PropertiesProvider> {
return String.join(".", parts);
}
public static <R> R doWithEntityManager(final EntityManager em, final Supplier<R> code) {
localEntityManager.set(em);
try {
return code.get();
} catch (final RuntimeException e) {
localEntityManager.remove();
throw e;
}
}
public abstract List<String> validateEntity(final E entity);
public abstract List<String> validateContext(final E entity);

View File

@ -5,7 +5,7 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.experimental.Accessors;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.mapper.Array;
import org.apache.commons.lang3.function.TriFunction;
@ -73,7 +73,7 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
private boolean isTotalsValidator = false;
@JsonIgnore
private List<Function<HsBookingItemEntity, List<String>>> asTotalLimitValidators; // TODO.impl: move to BookingItemIntegerProperty
private List<Function<HsBookingItem, List<String>>> asTotalLimitValidators; // TODO.impl: move to BookingItemIntegerProperty
private Integer thresholdPercentage; // TODO.impl: move to IntegerProperty
@ -151,8 +151,8 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
if (asTotalLimitValidators == null) {
asTotalLimitValidators = new ArrayList<>();
}
final TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> validator =
(final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> {
final TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> validator =
(final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var total = entity.getSubBookingItems().stream()
.map(server -> server.getResources().get(propertyName))
@ -167,7 +167,7 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
}
return emptyList();
};
asTotalLimitValidators.add((final HsBookingItemEntity entity) -> validator.apply(entity, (IntegerProperty)this, 1));
asTotalLimitValidators.add((final HsBookingItem entity) -> validator.apply(entity, (IntegerProperty)this, 1));
return self();
}
@ -183,11 +183,11 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
return thresholdPercentage;
}
public ValidatableProperty<P, T> eachComprising(final int factor, final TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> validator) {
public ValidatableProperty<P, T> eachComprising(final int factor, final TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> validator) {
if (asTotalLimitValidators == null) {
asTotalLimitValidators = new ArrayList<>();
}
asTotalLimitValidators.add((final HsBookingItemEntity entity) -> validator.apply(entity, (IntegerProperty<?>)this, factor));
asTotalLimitValidators.add((final HsBookingItem entity) -> validator.apply(entity, (IntegerProperty<?>)this, factor));
return this;
}
@ -323,7 +323,7 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
return value;
}
public List<String> validateTotals(final HsBookingItemEntity bookingItem) {
public List<String> validateTotals(final HsBookingItem bookingItem) {
if (asTotalLimitValidators==null) {
return emptyList();
}

View File

@ -11,7 +11,7 @@ import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.ConditionEvents;
import com.tngtech.archunit.lang.SimpleConditionEvent;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
@ -330,7 +330,7 @@ public class ArchitectureTest {
ContextBasedTest.class,
RbacGrantsDiagramService.class)
.ignoreDependency(
HsBookingItemEntity.class,
HsBookingItem.class,
HsHostingAssetRbacEntity.class);

View File

@ -0,0 +1,28 @@
package net.hostsharing.hsadminng.hs.booking;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.jetbrains.annotations.NotNull;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import java.util.Optional;
import java.util.stream.Stream;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class EntityManagerMock {
public static @NotNull EntityManager createEntityManagerMockWithAssetQueryFake(final HsHostingAssetRealEntity asset) {
final var em = mock(EntityManager.class);
final var assetQuery = mock(TypedQuery.class);
final var assetStream = mock(Stream.class);
when(em.createQuery(any(), any(Class.class))).thenReturn(assetQuery);
when(assetQuery.getResultStream()).thenReturn(assetStream);
when(assetQuery.setParameter(anyString(), any())).thenReturn(assetQuery);
when(assetStream.findFirst()).thenReturn(Optional.ofNullable(asset));
return em;
}
}

View File

@ -44,7 +44,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
private Integer port;
@Autowired
HsBookingItemRepository bookingItemRepo;
HsBookingItemRealRepository realBookingItemRepo;
@Autowired
HsBookingProjectRealRepository realProjectRepo;
@ -191,9 +191,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Order(1)
void globalAdmin_canGetArbitraryBookingItem() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedWebspace").stream()
final var givenBookingItemUuid = realBookingItemRepo.findByCaption("separate ManagedWebspace").stream()
.filter(bi -> belongsToProject(bi, "D-1000111 default project"))
.map(HsBookingItemEntity::getUuid)
.map(HsBookingItem::getUuid)
.findAny().orElseThrow();
RestAssured // @formatter:off
@ -225,9 +225,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Order(2)
void normalUser_canNotGetUnrelatedBookingItem() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedServer").stream()
final var givenBookingItemUuid = realBookingItemRepo.findByCaption("separate ManagedServer").stream()
.filter(bi -> belongsToProject(bi, "D-1000212 default project"))
.map(HsBookingItemEntity::getUuid)
.map(HsBookingItem::getUuid)
.findAny().orElseThrow();
RestAssured // @formatter:off
@ -244,7 +244,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Order(3)
void projectAdmin_canGetRelatedBookingItem() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingItem = bookingItemRepo.findByCaption("separate ManagedServer").stream()
final var givenBookingItem = realBookingItemRepo.findByCaption("separate ManagedServer").stream()
.filter(bi -> belongsToProject(bi, "D-1000313 default project"))
.findAny().orElseThrow();
@ -274,9 +274,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
""")); // @formatter:on
}
private static boolean belongsToProject(final HsBookingItemEntity bi, final String projectCaption) {
private static boolean belongsToProject(final HsBookingItem bi, final String projectCaption) {
return ofNullable(bi)
.map(HsBookingItemEntity::getProject)
.map(HsBookingItem::getProject)
.filter(bp -> bp.getCaption().equals(projectCaption))
.isPresent();
}
@ -328,7 +328,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
// finally, the bookingItem is actually updated
context.define("superuser-alex@hostsharing.net");
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get()
assertThat(realBookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)");
assertThat(mandate.getValidFrom()).isEqualTo("2022-11-01");
@ -358,7 +358,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(204); // @formatter:on
// then the given bookingItem is gone
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isEmpty();
assertThat(realBookingItemRepo.findByUuid(givenBookingItem.getUuid())).isEmpty();
}
@Test
@ -377,18 +377,18 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(404); // @formatter:on
// then the given bookingItem is still there
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isNotEmpty();
assertThat(realBookingItemRepo.findByUuid(givenBookingItem.getUuid())).isNotEmpty();
}
}
@SafeVarargs
private HsBookingItemEntity givenSomeNewBookingItem(final String projectCaption,
private HsBookingItem givenSomeNewBookingItem(final String projectCaption,
final HsBookingItemType hsBookingItemType, final Map.Entry<String, Object>... resources) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow();
final var newBookingItem = HsBookingItemEntity.builder()
final var newBookingItem = HsBookingItemRealEntity.builder()
.uuid(UUID.randomUUID())
.project(givenProject)
.type(hsBookingItemType)
@ -398,7 +398,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31")))
.build();
return bookingItemRepo.save(newBookingItem);
return realBookingItemRepo.save(newBookingItem);
}).assertSuccessful().returnedValue();
}

View File

@ -54,7 +54,7 @@ class HsBookingItemControllerRestTest {
HsBookingProjectRealRepository realProjectRepo;
@MockBean
HsBookingItemRepository bookingItemRepo;
HsBookingItemRbacRepository rbacBookingItemRepo;
@BeforeEach
void init() {
@ -78,7 +78,7 @@ class HsBookingItemControllerRestTest {
.uuid(invocation.getArgument(1))
.build()
);
when(bookingItemRepo.save(any())).thenAnswer(invocation -> invocation.getArgument(0));
when(rbacBookingItemRepo.save(any())).thenAnswer(invocation -> invocation.getArgument(0));
// when
mockMvc.perform(MockMvcRequestBuilders
@ -128,7 +128,7 @@ class HsBookingItemControllerRestTest {
.uuid(invocation.getArgument(1))
.build()
);
when(bookingItemRepo.save(any())).thenAnswer(invocation -> invocation.getArgument(0));
when(rbacBookingItemRepo.save(any())).thenAnswer(invocation -> invocation.getArgument(0));
// when
mockMvc.perform(MockMvcRequestBuilders

View File

@ -29,7 +29,7 @@ import static org.mockito.Mockito.lenient;
@ExtendWith(MockitoExtension.class)
class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
HsBookingItemPatchResource,
HsBookingItemEntity
HsBookingItem
> {
private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID();
@ -62,13 +62,13 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
void initMocks() {
lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsBookingItemEntity.class), any())).thenAnswer(invocation ->
HsBookingItemEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsBookingItem.class), any())).thenAnswer(invocation ->
HsBookingItemRbacEntity.builder().uuid(invocation.getArgument(1)).build());
}
@Override
protected HsBookingItemEntity newInitialEntity() {
final var entity = new HsBookingItemEntity();
protected HsBookingItem newInitialEntity() {
final var entity = new HsBookingItemRbacEntity();
entity.setUuid(INITIAL_BOOKING_ITEM_UUID);
entity.setProject(PROJECT_TEST_ENTITY);
entity.getResources().putAll(KeyValueMap.from(INITIAL_RESOURCES));
@ -83,7 +83,7 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
}
@Override
protected HsBookingItemEntityPatcher createPatcher(final HsBookingItemEntity bookingItem) {
protected HsBookingItemEntityPatcher createPatcher(final HsBookingItem bookingItem) {
return new HsBookingItemEntityPatcher(bookingItem);
}
@ -94,19 +94,19 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
"caption",
HsBookingItemPatchResource::setCaption,
PATCHED_CAPTION,
HsBookingItemEntity::setCaption),
HsBookingItem::setCaption),
new SimpleProperty<>(
"resources",
HsBookingItemPatchResource::setResources,
PATCH_RESOURCES,
HsBookingItemEntity::putResources,
HsBookingItem::putResources,
PATCHED_RESOURCES)
.notNullable(),
new JsonNullableProperty<>(
"validto",
HsBookingItemPatchResource::setValidTo,
PATCHED_VALID_TO,
HsBookingItemEntity::setValidTo)
HsBookingItem::setValidTo)
);
}
}

View File

@ -20,7 +20,7 @@ class HsBookingItemEntityUnitTest {
private MockedStatic<LocalDate> localDateMockedStatic = Mockito.mockStatic(LocalDate.class, Mockito.CALLS_REAL_METHODS);
final HsBookingItemEntity givenBookingItem = HsBookingItemEntity.builder()
final HsBookingItem givenBookingItem = HsBookingItemRbacEntity.builder()
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.CLOUD_SERVER)
.caption("some caption")
@ -43,7 +43,7 @@ class HsBookingItemEntityUnitTest {
localDateMockedStatic.when(LocalDate::now).thenReturn(fakedToday);
// when
final var newBookingItem = HsBookingItemEntity.builder().build();
final var newBookingItem = HsBookingItemRbacEntity.builder().build();
// then
assertThat(newBookingItem.getValidity().toString()).isEqualTo("Range{lower=2024-05-01, upper=null, mask=82, clazz=class java.time.LocalDate}");
@ -53,7 +53,7 @@ class HsBookingItemEntityUnitTest {
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
final var result = givenBookingItem.toString();
assertThat(result).isEqualToIgnoringWhitespace("HsBookingItemEntity(CLOUD_SERVER, some caption, D-1234500:test project, [2020-01-01,2031-01-01), { \"CPU\": 2, \"HDD-storage\": 2048, \"SSD-storage\": 512 })");
assertThat(result).isEqualToIgnoringWhitespace("HsBookingItem(CLOUD_SERVER, some caption, D-1234500:test project, [2020-01-01,2031-01-01), { \"CPU\": 2, \"HDD-storage\": 2048, \"SSD-storage\": 512 })");
}
@Test

View File

@ -39,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired
HsBookingItemRepository bookingItemRepo;
HsBookingItemRbacRepository rbacBookingItemRepo;
@Autowired
HsBookingProjectRealRepository realProjectRepo;
@ -69,27 +69,27 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingItem() {
// given
context("superuser-alex@hostsharing.net");
final var count = bookingItemRepo.count();
final var count = rbacBookingItemRepo.count();
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0);
final var givenProject = realProjectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
// when
final var result = attempt(em, () -> {
final var newBookingItem = HsBookingItemEntity.builder()
final var newBookingItem = HsBookingItemRbacEntity.builder()
.project(givenProject)
.type(HsBookingItemType.CLOUD_SERVER)
.caption("some new booking item")
.validity(Range.closedOpen(
LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01")))
.build();
return toCleanup(bookingItemRepo.save(newBookingItem));
return toCleanup(rbacBookingItemRepo.save(newBookingItem));
});
// then
result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingItemEntity::getUuid).isNotNull();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingItem::getUuid).isNotNull();
assertThatBookingItemIsPersisted(result.returnedValue());
assertThat(bookingItemRepo.count()).isEqualTo(count + 1);
assertThat(rbacBookingItemRepo.count()).isEqualTo(count + 1);
}
@Test
@ -103,14 +103,14 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
attempt(em, () -> {
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0);
final var givenProject = realProjectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
final var newBookingItem = HsBookingItemEntity.builder()
final var newBookingItem = HsBookingItemRbacEntity.builder()
.project(givenProject)
.type(MANAGED_WEBSPACE)
.caption("some new booking item")
.validity(Range.closedOpen(
LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01")))
.build();
return toCleanup(bookingItemRepo.save(newBookingItem));
return toCleanup(rbacBookingItemRepo.save(newBookingItem));
});
// then
@ -146,9 +146,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
null));
}
private void assertThatBookingItemIsPersisted(final HsBookingItemEntity saved) {
final var found = bookingItemRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingItemEntity::toString).get().isEqualTo(saved.toString());
private void assertThatBookingItemIsPersisted(final HsBookingItem saved) {
final var found = rbacBookingItemRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingItem::toString).get().isEqualTo(saved.toString());
}
}
@ -165,17 +165,14 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
.findAny().orElseThrow().getUuid();
// when
final var result = bookingItemRepo.findAllByProjectUuid(projectUuid);
final var result = rbacBookingItemRepo.findAllByProjectUuid(projectUuid);
// then
allTheseBookingItemsAreReturned(
result,
"HsBookingItemEntity(MANAGED_SERVER, separate ManagedServer, D-1000212:D-1000212 default project, [2022-10-01,), { CPU: 2, RAM: 8, SSD: 500, Traffic: 500 })",
"HsBookingItemEntity(MANAGED_WEBSPACE, separate ManagedWebspace, D-1000212:D-1000212 default project, [2022-10-01,), { Daemons: 0, Multi: 1, SSD: 100, Traffic: 50 })",
"HsBookingItemEntity(PRIVATE_CLOUD, some PrivateCloud, D-1000212:D-1000212 default project, [2024-04-01,), { CPU: 10, HDD: 10000, RAM: 32, SSD: 4000, Traffic: 2000 })");
assertThat(result.stream().filter(bi -> bi.getRelatedHostingAsset()!=null).findAny())
.as("at least one relatedProject expected, but none found => fetching relatedProject does not work")
.isNotEmpty();
"HsBookingItem(MANAGED_SERVER, separate ManagedServer, D-1000212:D-1000212 default project, [2022-10-01,), { CPU: 2, RAM: 8, SSD: 500, Traffic: 500 })",
"HsBookingItem(MANAGED_WEBSPACE, separate ManagedWebspace, D-1000212:D-1000212 default project, [2022-10-01,), { Daemons: 0, Multi: 1, SSD: 100, Traffic: 50 })",
"HsBookingItem(PRIVATE_CLOUD, some PrivateCloud, D-1000212:D-1000212 default project, [2024-04-01,), { CPU: 10, HDD: 10000, RAM: 32, SSD: 4000, Traffic: 2000 })");
}
@Test
@ -190,14 +187,14 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
.findAny().orElseThrow().getUuid();
// when:
final var result = bookingItemRepo.findAllByProjectUuid(projectUuid);
final var result = rbacBookingItemRepo.findAllByProjectUuid(projectUuid);
// then:
exactlyTheseBookingItemsAreReturned(
result,
"HsBookingItemEntity(MANAGED_SERVER, separate ManagedServer, D-1000111:D-1000111 default project, [2022-10-01,), { CPU : 2, RAM : 8, SSD : 500, Traffic : 500 })",
"HsBookingItemEntity(MANAGED_WEBSPACE, separate ManagedWebspace, D-1000111:D-1000111 default project, [2022-10-01,), { Daemons : 0, Multi : 1, SSD : 100, Traffic : 50 })",
"HsBookingItemEntity(PRIVATE_CLOUD, some PrivateCloud, D-1000111:D-1000111 default project, [2024-04-01,), { CPU : 10, HDD : 10000, RAM : 32, SSD : 4000, Traffic : 2000 })");
"HsBookingItem(MANAGED_SERVER, separate ManagedServer, D-1000111:D-1000111 default project, [2022-10-01,), { CPU : 2, RAM : 8, SSD : 500, Traffic : 500 })",
"HsBookingItem(MANAGED_WEBSPACE, separate ManagedWebspace, D-1000111:D-1000111 default project, [2022-10-01,), { Daemons : 0, Multi : 1, SSD : 100, Traffic : 50 })",
"HsBookingItem(PRIVATE_CLOUD, some PrivateCloud, D-1000111:D-1000111 default project, [2024-04-01,), { CPU : 10, HDD : 10000, RAM : 32, SSD : 4000, Traffic : 2000 })");
}
}
@ -212,13 +209,13 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
final var foundBookingItem = em.find(HsBookingItemEntity.class, givenBookingItemUuid);
final var foundBookingItem = em.find(HsBookingItemRbacEntity.class, givenBookingItemUuid);
foundBookingItem.getResources().put("CPU", 2);
foundBookingItem.getResources().remove("SSD-storage");
foundBookingItem.getResources().put("HSD-storage", 2048);
foundBookingItem.setValidity(Range.closedOpen(
LocalDate.parse("2019-05-17"), LocalDate.parse("2023-01-01")));
return toCleanup(bookingItemRepo.save(foundBookingItem));
return toCleanup(rbacBookingItemRepo.save(foundBookingItem));
});
// then
@ -229,10 +226,10 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
}).assertSuccessful();
}
private void assertThatBookingItemActuallyInDatabase(final HsBookingItemEntity saved) {
final var found = bookingItemRepo.findByUuid(saved.getUuid());
private void assertThatBookingItemActuallyInDatabase(final HsBookingItem saved) {
final var found = rbacBookingItemRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved)
.extracting(HsBookingItemEntity::getResources)
.extracting(HsBookingItem::getResources)
.extracting(Object::toString)
.isEqualTo(saved.getResources().toString());
}
@ -250,14 +247,14 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
bookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
rbacBookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
});
// then
result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null);
return bookingItemRepo.findByUuid(givenBookingItem.getUuid());
return rbacBookingItemRepo.findByUuid(givenBookingItem.getUuid());
}).assertSuccessful().returnedValue()).isEmpty();
}
@ -270,9 +267,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when
final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent();
assertThat(rbacBookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent();
bookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
rbacBookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
});
// then
@ -281,7 +278,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
"[403] Subject ", " is not allowed to delete hs_booking_item");
assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return bookingItemRepo.findByUuid(givenBookingItem.getUuid());
return rbacBookingItemRepo.findByUuid(givenBookingItem.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there
}
@ -296,7 +293,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return bookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
return rbacBookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
});
// then
@ -314,7 +311,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
select currentTask, targetTable, targetOp
from tx_journal_v
where targettable = 'hs_booking_item';
""");
""");
// when
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
@ -326,12 +323,12 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
"[creating booking-item test-data 1000313, hs_booking_item, INSERT]");
}
private HsBookingItemEntity givenSomeTemporaryBookingItem(final String projectCaption) {
private HsBookingItem givenSomeTemporaryBookingItem(final String projectCaption) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow();
final var newBookingItem = HsBookingItemEntity.builder()
final var newBookingItem = HsBookingItemRbacEntity.builder()
.project(givenProject)
.type(MANAGED_SERVER)
.caption("some temp booking item")
@ -342,23 +339,23 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
entry("SSD-storage", 256)))
.build();
return toCleanup(bookingItemRepo.save(newBookingItem));
return toCleanup(rbacBookingItemRepo.save(newBookingItem));
}).assertSuccessful().returnedValue();
}
void exactlyTheseBookingItemsAreReturned(
final List<HsBookingItemEntity> actualResult,
final List<? extends HsBookingItem> actualResult,
final String... bookingItemNames) {
assertThat(actualResult)
.extracting(HsBookingItemEntity::toString)
.extracting(HsBookingItem::toString)
.extracting(string-> string.replaceAll("\\s+", " "))
.extracting(string-> string.replaceAll("\"", ""))
.containsExactlyInAnyOrder(bookingItemNames);
}
void allTheseBookingItemsAreReturned(final List<HsBookingItemEntity> actualResult, final String... bookingItemNames) {
void allTheseBookingItemsAreReturned(final List<? extends HsBookingItem> actualResult, final String... bookingItemNames) {
assertThat(actualResult)
.extracting(HsBookingItemEntity::toString)
.extracting(HsBookingItem::toString)
.extracting(string -> string.replaceAll("\\s+", " "))
.extracting(string -> string.replaceAll("\"", ""))
.extracting(string -> string.replaceAll(" : ", ": "))

View File

@ -12,7 +12,7 @@ import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.
@UtilityClass
public class TestHsBookingItem {
public static final HsBookingItemEntity TEST_CLOUD_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
public static final HsBookingItemRealEntity CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY = HsBookingItemRealEntity.builder()
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.CLOUD_SERVER)
.caption("test cloud server booking item")
@ -25,7 +25,7 @@ public class TestHsBookingItem {
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
.build();
public static final HsBookingItemEntity TEST_MANAGED_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
public static final HsBookingItemRealEntity MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY = HsBookingItemRealEntity.builder()
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.MANAGED_SERVER)
.caption("test project booking item")
@ -38,8 +38,8 @@ public class TestHsBookingItem {
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
.build();
public static final HsBookingItemEntity TEST_MANAGED_WEBSPACE_BOOKING_ITEM = HsBookingItemEntity.builder()
.parentItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
public static final HsBookingItemRealEntity MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY = HsBookingItemRealEntity.builder()
.parentItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsBookingItemType.MANAGED_WEBSPACE)
.caption("test managed webspace item")
.resources(Map.ofEntries(

View File

@ -1,10 +1,11 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import jakarta.validation.ValidationException;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
@ -23,17 +24,19 @@ class HsBookingItemEntityValidatorUnitTest {
.caption("test project")
.build();
private EntityManager em;
@Test
void rejectsInvalidEntity() {
// given
final var cloudServerBookingItemEntity = HsBookingItemEntity.builder()
final var cloudServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER)
.project(project)
.caption("Test-Server")
.build();
// when
final var result = catchThrowable( ()-> HsBookingItemEntityValidatorRegistry.validated(cloudServerBookingItemEntity));
final var result = catchThrowable( ()-> HsBookingItemEntityValidatorRegistry.validated(em, cloudServerBookingItemEntity));
// then
assertThat(result).isInstanceOf(ValidationException.class)

View File

@ -1,10 +1,11 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import java.util.Map;
import static java.util.List.of;
@ -24,11 +25,12 @@ class HsCloudServerBookingItemValidatorUnitTest {
.debitor(debitor)
.caption("Test-Project")
.build();
private EntityManager em;
@Test
void validatesProperties() {
// given
final var cloudServerBookingItemEntity = HsBookingItemEntity.builder()
final var cloudServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER)
.project(project)
.caption("Test-Server")
@ -42,7 +44,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
.build();
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(cloudServerBookingItemEntity);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, cloudServerBookingItemEntity);
// then
assertThat(result).containsExactly("'D-12345:Test-Project:Test-Server.resources.SLA-EMail' is not expected but is set to 'true'");
@ -68,7 +70,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
@Test
void validatesExceedingPropertyTotals() {
// given
final var subCloudServerBookingItemEntity = HsBookingItemEntity.builder()
final var subCloudServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER)
.caption("Test Cloud-Server")
.resources(ofEntries(
@ -78,7 +80,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
entry("Traffic", 2500)
))
.build();
final HsBookingItemEntity subManagedServerBookingItemEntity = HsBookingItemEntity.builder()
final HsBookingItemRealEntity subManagedServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER)
.caption("Test Managed-Server")
.resources(ofEntries(
@ -88,7 +90,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
entry("Traffic", 3000)
))
.build();
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
final var privateCloudBookingItemEntity = HsBookingItemRealEntity.builder()
.type(PRIVATE_CLOUD)
.project(project)
.caption("Test Cloud")
@ -107,7 +109,7 @@ class HsCloudServerBookingItemValidatorUnitTest {
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(subCloudServerBookingItemEntity);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, subCloudServerBookingItemEntity);
// then
assertThat(result).containsExactlyInAnyOrder(

View File

@ -1,11 +1,14 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.EntityManagerMock;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Collection;
import java.util.List;
@ -17,12 +20,14 @@ import static java.util.Arrays.stream;
import static java.util.List.of;
import static java.util.Map.entry;
import static java.util.Map.ofEntries;
import static net.hostsharing.hsadminng.hs.booking.EntityManagerMock.createEntityManagerMockWithAssetQueryFake;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsManagedServerBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
@ -36,7 +41,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
@Test
void validatesProperties() {
// given
final var mangedServerBookingItemEntity = HsBookingItemEntity.builder()
final var mangedServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER)
.project(project)
.resources(Map.ofEntries(
@ -48,9 +53,10 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("SLA-EMail", true)
))
.build();
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, mangedServerBookingItemEntity);
// then
assertThat(result).containsExactly("'D-12345:Test-Project:null.resources.SLA-EMail' is expected to be false because SLA-Platform=BASIC but is true");
@ -80,7 +86,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
@Test
void validatesExceedingPropertyTotals() {
// given
final var subCloudServerBookingItemEntity = HsBookingItemEntity.builder()
final var subCloudServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER)
.resources(ofEntries(
entry("CPU", 2),
@ -89,7 +95,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 2500)
))
.build();
final HsBookingItemEntity subManagedServerBookingItemEntity = HsBookingItemEntity.builder()
final HsBookingItemRealEntity subManagedServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER)
.resources(ofEntries(
entry("CPU", 3),
@ -98,7 +104,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 3000)
))
.build();
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
final var privateCloudBookingItemEntity = HsBookingItemRealEntity.builder()
.type(PRIVATE_CLOUD)
.project(project)
.resources(ofEntries(
@ -116,8 +122,10 @@ class HsManagedServerBookingItemValidatorUnitTest {
subManagedServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(subManagedServerBookingItemEntity);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, subManagedServerBookingItemEntity);
// then
assertThat(result).containsExactlyInAnyOrder(
@ -131,7 +139,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
@Test
void validatesExceedingTotals() {
// given
final var managedWebspaceBookingItem = HsBookingItemEntity.builder()
final var managedWebspaceBookingItem = HsBookingItemRealEntity.builder()
.type(MANAGED_WEBSPACE)
.project(project)
.caption("test Managed-Webspace")
@ -140,7 +148,8 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 1000),
entry("Multi", 1)
))
.relatedHostingAsset(HsHostingAssetRealEntity.builder()
.build();
final var em = createEntityManagerMockWithAssetQueryFake(HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("abc00")
.subHostingAssets(concat(
@ -157,13 +166,11 @@ class HsManagedServerBookingItemValidatorUnitTest {
"%c%c.example.com",
10, HsHostingAssetType.EMAIL_ADDRESS
)
))
.build()
)
.build();
))
.build());
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(managedWebspaceBookingItem);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, managedWebspaceBookingItem);
// then
assertThat(result).containsExactlyInAnyOrder(

View File

@ -1,10 +1,11 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import java.util.Map;
import static java.util.Map.entry;
@ -20,11 +21,12 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
.debitor(debitor)
.caption("Test-Project")
.build();
private EntityManager em;
@Test
void validatesProperties() {
// given
final var mangedServerBookingItemEntity = HsBookingItemEntity.builder()
final var mangedServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(MANAGED_WEBSPACE)
.project(project)
.caption("Test Managed-Webspace")
@ -37,7 +39,7 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
.build();
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, mangedServerBookingItemEntity);
// then
assertThat(result).containsExactlyInAnyOrder(

View File

@ -1,10 +1,12 @@
package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import static java.util.List.of;
import static java.util.Map.entry;
import static java.util.Map.ofEntries;
@ -23,11 +25,12 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
.debitor(debitor)
.caption("Test-Project")
.build();
private EntityManager em;
@Test
void validatesPropertyTotals() {
// given
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
final var privateCloudBookingItemEntity = HsBookingItemRealEntity.builder()
.type(PRIVATE_CLOUD)
.project(PROJECT_TEST_ENTITY)
.caption("myPC")
@ -40,7 +43,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", 2)
))
.subBookingItems(of(
HsBookingItemEntity.builder()
HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER)
.caption("myMS-1")
.resources(ofEntries(
@ -52,7 +55,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", true)
))
.build(),
HsBookingItemEntity.builder()
HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER)
.caption("myMS-2")
.resources(ofEntries(
@ -68,7 +71,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
.build();
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, privateCloudBookingItemEntity);
// then
assertThat(result).isEmpty();
@ -77,7 +80,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
@Test
void validatesExceedingPropertyTotals() {
// given
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder()
final var privateCloudBookingItemEntity = HsBookingItemRealEntity.builder()
.project(project)
.type(PRIVATE_CLOUD)
.caption("myPC")
@ -90,7 +93,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", 1)
))
.subBookingItems(of(
HsBookingItemEntity.builder()
HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER)
.caption("myMS-1")
.resources(ofEntries(
@ -102,7 +105,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", true)
))
.build(),
HsBookingItemEntity.builder()
HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER)
.caption("myMS-2")
.resources(ofEntries(
@ -122,7 +125,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
.build();
// when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity);
final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, privateCloudBookingItemEntity);
// then
assertThat(result).containsExactlyInAnyOrder(

View File

@ -38,14 +38,11 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
void initMocks() {
lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
// FIXME
// lenient().when(em.getReference(eq(HsBookingProject.class), any())).thenAnswer(invocation ->
// HsBookingProject.builder().uuid(invocation.getArgument(1)).build());
}
@Override
protected HsBookingProject newInitialEntity() {
final var entity = new HsBookingProject();
final var entity = new HsBookingProjectRbacEntity();
entity.setUuid(INITIAL_BOOKING_PROJECT_UUID);
entity.setDebitor(TEST_BOOKING_DEBITOR);
entity.setCaption(INITIAL_CAPTION);

View File

@ -60,9 +60,8 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
@Nested
class CreateBookingProject {
@ParameterizedTest
@EnumSource(TestCase.class)
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject(final TestCase testCase) {
@Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject() {
// given
context("superuser-alex@hostsharing.net"); // TODO.test: remove once we have a realDebitorRepo
final var count = realProjectRepo.count();
@ -74,7 +73,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(repoUnderTest(testCase).save(newBookingProject));
return toCleanup(rbacProjectRepo.save(newBookingProject));
});
// then
@ -84,9 +83,8 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
assertThat(realProjectRepo.count()).isEqualTo(count + 1);
}
@ParameterizedTest
@EnumSource(TestCase.class)
public void createsAndGrantsRoles(final TestCase testCase) {
@Test
public void createsAndGrantsRoles() {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = distinctRoleNamesOf(rawRoleRepo.findAll());
@ -101,7 +99,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(repoUnderTest(testCase).save(newBookingProject));
return toCleanup(rbacProjectRepo.save(newBookingProject));
});
// then

View File

@ -4,8 +4,9 @@ import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.hash.HashGenerator;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
@ -53,16 +54,16 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
HsHostingAssetRealRepository realAssetRepo;
@Autowired
HsHostingAssetRbacRepository rbacAssetRepo;
HsHostingAssetRbacRepository rbacAssetRepo; // FIXME: remove?
@Autowired
HsBookingItemRepository bookingItemRepo;
HsBookingItemRealRepository realBookingItemRepo;
@Autowired
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
HsOfficeDebitorRepository debitorRepo; // FIXME: remove?
@Autowired
HsOfficeContactRealRepository realContactRepo;
@ -680,24 +681,24 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
.findAny().orElseThrow();
}
HsBookingItemEntity newBookingItem(
HsBookingItem newBookingItem(
final String projectCaption,
final HsBookingItemType type, final String bookingItemCaption, final Map<String, Object> resources) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var project = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow();
final var bookingItem = HsBookingItemEntity.builder()
final var bookingItem = HsBookingItemRealEntity.builder()
.project(project)
.type(type)
.caption(bookingItemCaption)
.resources(resources)
.build();
return toCleanup(bookingItemRepo.save(bookingItem));
return toCleanup(realBookingItemRepo.save(bookingItem));
}).assertSuccessful().returnedValue();
}
HsBookingItemEntity givenSomeNewBookingItem(
HsBookingItemRealEntity givenSomeNewBookingItem(
final String projectCaption,
final HsBookingItemType bookingItemType,
final String bookingItemCaption) {
@ -711,13 +712,13 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
entry("Traffic", 250));
default -> new HashMap<String, Object>();
};
final var newBookingItem = HsBookingItemEntity.builder()
final var newBookingItem = HsBookingItemRealEntity.builder()
.project(project)
.type(bookingItemType)
.caption(bookingItemCaption)
.resources(resources)
.build();
return toCleanup(bookingItemRepo.save(newBookingItem));
return toCleanup(realBookingItemRepo.save(newBookingItem));
}).assertSuccessful().returnedValue();
}

View File

@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
import net.hostsharing.hsadminng.mapper.Array;
import net.hostsharing.hsadminng.mapper.Mapper;
import org.junit.jupiter.api.BeforeEach;
@ -28,8 +28,8 @@ import java.util.List;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY;
import static net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealTestEntity.TEST_REAL_CONTACT;
@ -62,7 +62,7 @@ public class HsHostingAssetControllerRestTest {
@MockBean
@SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController
private HsBookingItemRepository bookingItemRepo;
private HsBookingItemRealRepository realBookingItemRepo;
@MockBean
private HsHostingAssetRealRepository realAssetRepo;
@ -75,7 +75,7 @@ public class HsHostingAssetControllerRestTest {
List.of(
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.CLOUD_SERVER)
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.identifier("vm1234")
.caption("some fake cloud-server")
.alarmContact(TEST_REAL_CONTACT)
@ -101,7 +101,7 @@ public class HsHostingAssetControllerRestTest {
List.of(
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MANAGED_SERVER)
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.identifier("vm1234")
.caption("some fake managed-server")
.alarmContact(TEST_REAL_CONTACT)

View File

@ -15,7 +15,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static net.hostsharing.hsadminng.mapper.PatchMap.patchMap;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
@ -70,7 +70,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
protected HsHostingAssetRbacEntity newInitialEntity() {
final var entity = new HsHostingAssetRbacEntity();
entity.setUuid(INITIAL_BOOKING_ITEM_UUID);
entity.setBookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM);
entity.setBookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY);
entity.getConfig().putAll(KeyValueMap.from(INITIAL_CONFIG));
entity.setCaption(INITIAL_CAPTION);
entity.setAlarmContact(givenInitialContact);

View File

@ -5,13 +5,13 @@ import org.junit.jupiter.api.Test;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static org.assertj.core.api.Assertions.assertThat;
class HsHostingAssetEntityUnitTest {
final HsHostingAssetRealEntity givenParentAsset = HsHostingAssetRealEntity.builder()
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234")
.caption("some managed asset")
@ -21,7 +21,7 @@ class HsHostingAssetEntityUnitTest {
entry("HDD-storage", 2048)))
.build();
final HsHostingAssetRealEntity givenWebspace = HsHostingAssetRealEntity.builder()
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.parentAsset(givenParentAsset)
.identifier("xyz00")

View File

@ -1,8 +1,8 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRbacRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
@ -48,7 +48,7 @@ class HsHostingAssetRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
HsHostingAssetRbacRepository rbacAssetRepo;
@Autowired
HsBookingItemRepository bookingItemRepo;
HsBookingItemRealRepository realBookingItemRepo;
@Autowired
HsBookingProjectRbacRepository projectRepo;
@ -425,8 +425,8 @@ class HsHostingAssetRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
}).assertSuccessful().returnedValue();
}
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
return bookingItemRepo.findByCaption(bookingItemCaption).stream()
HsBookingItemRealEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
return realBookingItemRepo.findByCaption(bookingItemCaption).stream()
.filter(i -> i.getRelatedProject().getCaption().equals(projectCaption))
.findAny().orElseThrow();
}
@ -438,16 +438,16 @@ class HsHostingAssetRbacRepositoryIntegrationTest extends ContextBasedTestWithCl
.findAny().orElseThrow();
}
HsBookingItemEntity newBookingItem(
final HsBookingItemEntity parentBookingItem,
HsBookingItemRealEntity newBookingItem(
final HsBookingItemRealEntity parentBookingItem,
final HsBookingItemType type,
final String caption) {
final var newBookingItem = HsBookingItemEntity.builder()
final var newBookingItem = HsBookingItemRealEntity.builder()
.parentItem(parentBookingItem)
.type(type)
.caption(caption)
.build();
return toCleanup(bookingItemRepo.save(newBookingItem));
return toCleanup(realBookingItemRepo.save(newBookingItem));
}
void exactlyTheseAssetsAreReturned(

View File

@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_WEBSPACE_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY;
public class HsHostingAssetTestEntities {
@ -9,28 +9,28 @@ public class HsHostingAssetTestEntities {
.type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234")
.caption("some managed server")
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.build();
public static final HsHostingAssetRealEntity MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234")
.caption("some managed server")
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.build();
public static final HsHostingAssetRbacEntity MANAGED_WEBSPACE_HOSTING_ASSET_RBAC_TEST_ENTITY = HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("xyz00")
.caption("some managed webspace")
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM)
.bookingItem(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.build();
public static final HsHostingAssetRealEntity MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("xyz00")
.caption("some managed webspace")
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM)
.bookingItem(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.build();
}

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
import static org.assertj.core.api.Assertions.assertThat;
@ -44,7 +44,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
final var cloudServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(CLOUD_SERVER)
.identifier("xyz99")
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(cloudServerHostingAssetEntity.getType());
@ -72,7 +72,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_SERVER)
.identifier("xyz00")
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
@ -90,7 +90,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(CLOUD_SERVER)
.identifier("vm1234")
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.build();

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -8,6 +8,7 @@ import net.hostsharing.hsadminng.mapper.Array;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import java.util.ArrayList;
import java.util.Map;
@ -30,6 +31,8 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
.identifier("example.org")
.build();
private EntityManager em;
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(DOMAIN_DNS_SETUP)
@ -139,7 +142,7 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(null)
.assignedToAsset(HsHostingAssetRealEntity.builder().type(DOMAIN_SETUP).build())
.build();

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -109,7 +109,7 @@ class HsDomainHttpSetupHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(null)
.build();

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -84,7 +84,7 @@ class HsDomainMboxHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(null)
.build();

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -96,7 +96,7 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
final var mangedServerHostingAssetEntity = validEntityBuilder()
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder;
@ -85,7 +85,7 @@ class HsDomainSmtpSetupHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(null)
.build();

View File

@ -9,7 +9,7 @@ import java.util.HashMap;
import java.util.Map;
import static java.util.Map.ofEntries;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_MBOX_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ADDRESS;
@ -174,7 +174,7 @@ class HsEMailAddressHostingAssetValidatorUnitTest {
void validatesInvalidReferences() {
// given
final var emailAddressHostingAssetEntity = validEntityBuilder()
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.assignedToAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.build();

View File

@ -7,7 +7,7 @@ import org.junit.jupiter.api.Test;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ALIAS;
@ -127,7 +127,7 @@ class HsEMailAliasHostingAssetValidatorUnitTest {
// given
final var emailAliasHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(EMAIL_ALIAS)
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.assignedToAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("abc00-office")

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -84,7 +84,7 @@ class HsIPv4NumberHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var ipNumberHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(UNIX_USER).build())
.build();

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -84,7 +84,7 @@ class HsIPv6NumberHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var ipNumberHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(UNIX_USER).build())
.build();

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -9,8 +9,8 @@ import org.junit.jupiter.api.Test;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_CLOUD_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
import static org.assertj.core.api.Assertions.assertThat;
@ -23,7 +23,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_SERVER)
.identifier("vm1234")
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.config(Map.ofEntries(
@ -52,7 +52,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_SERVER)
.identifier("xyz00")
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.MANAGED_SERVER).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
@ -70,7 +70,7 @@ class HsManagedServerHostingAssetValidatorUnitTest {
final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_SERVER)
.identifier("xyz00")
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
.build();

View File

@ -1,11 +1,15 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.EntityManagerMock;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Map;
import java.util.stream.Stream;
@ -16,9 +20,10 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANA
import static org.assertj.core.api.Assertions.assertThat;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
@ExtendWith(MockitoExtension.class)
class HsManagedWebspaceHostingAssetValidatorUnitTest {
final HsBookingItemEntity managedServerBookingItem = HsBookingItemEntity.builder()
final HsBookingItemRealEntity managedServerBookingItem = HsBookingItemRealEntity.builder()
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.MANAGED_SERVER)
.caption("Test Managed-Server")
@ -31,7 +36,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
entry("SLA-EMail", true)
))
.build();
final HsBookingItemEntity cloudServerBookingItem = managedServerBookingItem.toBuilder()
final HsBookingItemRealEntity cloudServerBookingItem = managedServerBookingItem.toBuilder()
.type(HsBookingItemType.CLOUD_SERVER)
.caption("Test Cloud-Server")
.build();
@ -63,7 +68,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder()
.bookingItem(HsBookingItemRealEntity.builder()
.type(HsBookingItemType.MANAGED_WEBSPACE)
.resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250)))
.build())
@ -71,9 +76,11 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
.identifier("xyz00")
.isLoaded(true)
.build();
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = validator.validateContext(mangedWebspaceHostingAssetEntity);
final var result = HsEntityValidator.doWithEntityManager(em, () ->
validator.validateContext(mangedWebspaceHostingAssetEntity));
// then
assertThat(result).isEmpty();
@ -85,7 +92,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
.parentAsset(mangedServerAssetEntity)
.identifier("xyz00")
.build();
@ -103,7 +110,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
.parentAsset(mangedServerAssetEntity)
.identifier("abc00")
.config(Map.ofEntries(
@ -124,7 +131,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder()
.bookingItem(HsBookingItemRealEntity.builder()
.type(HsBookingItemType.MANAGED_WEBSPACE)
.project(PROJECT_TEST_ENTITY)
.caption("some ManagedWebspace")
@ -133,12 +140,14 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
.parentAsset(mangedServerAssetEntity)
.identifier("abc00")
.build();
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = Stream.concat(
final var result = HsEntityValidator.doWithEntityManager(em, () ->
Stream.concat(
validator.validateEntity(mangedWebspaceHostingAssetEntity).stream(),
validator.validateContext(mangedWebspaceHostingAssetEntity).stream())
.toList();
.toList());
// then
assertThat(result).isEmpty();
@ -150,7 +159,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder()
.bookingItem(HsBookingItemRealEntity.builder()
.type(HsBookingItemType.MANAGED_SERVER)
.caption("some ManagedServer")
.resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250)))

View File

@ -3,7 +3,11 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import jakarta.persistence.EntityManager;
import java.util.HashMap;
import java.util.stream.Stream;
@ -16,6 +20,7 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARI
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
private static final HsHostingAssetRealEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetRealEntity.builder()
@ -36,6 +41,9 @@ class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
)))
.build();
@Mock
private EntityManager em;
private static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder givenValidMariaDbDatabaseBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(MARIADB_DATABASE)

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -80,7 +80,7 @@ class HsMariaDbInstanceHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.build();

View File

@ -3,6 +3,9 @@ package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import jakarta.persistence.EntityManager;
import java.util.HashMap;
@ -16,6 +19,7 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARI
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsMariaDbUserHostingAssetValidatorUnitTest {
private static final HsHostingAssetRealEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetRealEntity.builder()
@ -25,7 +29,8 @@ class HsMariaDbUserHostingAssetValidatorUnitTest {
.caption("some valid test MariaDB-Instance")
.build();
private EntityManager em = null; // not actually needed in these test cases
@Mock
private EntityManager em;
private static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> givenValidMariaDbUserBuilder() {
return HsHostingAssetRbacEntity.builder()

View File

@ -1,10 +1,12 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.HashMap;
import java.util.stream.Stream;
@ -18,6 +20,7 @@ import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQ
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
private static final HsHostingAssetRealEntity GIVEN_PGSQL_INSTANCE = HsHostingAssetRealEntity.builder()
@ -83,7 +86,7 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
void rejectsInvalidReferences() {
// given
final var givenPgSqlUserHostingAsset = givenValidPgSqlDatabaseBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(PGSQL_INSTANCE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(PGSQL_INSTANCE).build())
.build();

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
@ -80,7 +80,7 @@ class HsPostgreSqlInstanceHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.build();

View File

@ -16,8 +16,8 @@ import java.util.HashMap;
import java.util.stream.Stream;
import static java.util.Map.ofEntries;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_SERVER_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.TEST_MANAGED_WEBSPACE_BOOKING_ITEM;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.booking.item.TestHsBookingItem.MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
@ -32,17 +32,17 @@ class HsUnixUserHostingAssetValidatorUnitTest {
.type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234")
.caption("some managed server")
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.build();
private final HsHostingAssetRealEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET_REAL_ENTITY = HsHostingAssetRealEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM)
.bookingItem(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00")
.build();
private final HsHostingAssetRbacEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET_RBAC_ENTITY = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM)
.bookingItem(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00")
.build();

View File

@ -6,7 +6,8 @@ import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hash.HashGenerator;
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
@ -132,7 +133,7 @@ public class ImportHostingAssets extends ImportOfficeData {
record Hive(int hive_id, String hive_name, int inet_addr_id, AtomicReference<HsHostingAssetRealEntity> serverRef) {}
static Map<Integer, HsBookingProjectRealEntity> bookingProjects = new WriteOnceMap<>();
static Map<Integer, HsBookingItemEntity> bookingItems = new WriteOnceMap<>();
static Map<Integer, HsBookingItem> bookingItems = new WriteOnceMap<>();
static Map<Integer, Hive> hives = new WriteOnceMap<>();
static Map<Integer, HsHostingAssetRealEntity> ipNumberAssets = new WriteOnceMap<>();
@ -610,7 +611,7 @@ public class ImportHostingAssets extends ImportOfficeData {
void validateBookingItems() {
bookingItems.forEach((id, bi) -> {
try {
HsBookingItemEntityValidatorRegistry.validated(bi);
HsBookingItemEntityValidatorRegistry.validated(em, bi);
} catch (final Exception exc) {
errors.add("validation failed for id:" + id + "( " + bi + "): " + exc.getMessage());
}
@ -959,11 +960,11 @@ public class ImportHostingAssets extends ImportOfficeData {
return zonenfileName.substring(zonenfileName.length() - "vm0000.json".length()).substring(0, 6);
}
private void persistRecursively(final Integer key, final HsBookingItemEntity bi) {
private void persistRecursively(final Integer key, final HsBookingItem bi) {
if (bi.getParentItem() != null) {
persistRecursively(key, HsBookingItemEntityValidatorRegistry.validated(bi.getParentItem()));
persistRecursively(key, HsBookingItemEntityValidatorRegistry.validated(em, bi.getParentItem()));
}
persist(key, HsBookingItemEntityValidatorRegistry.validated(bi));
persist(key, HsBookingItemEntityValidatorRegistry.validated(em, bi));
}
private void persistHostingAssets(final Map<Integer, HsHostingAssetRealEntity> assets) {
@ -1065,7 +1066,7 @@ public class ImportHostingAssets extends ImportOfficeData {
.isNull();
final var biType = determineBiType(basepacket_code);
final var bookingItem = HsBookingItemEntity.builder()
final var bookingItem = HsBookingItemRealEntity.builder()
.type(biType)
.caption("BI " + packet_name)
.project(bookingProjects.get(bp_id))