real rbac-entities in booking+hosting (#89)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: #89
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig 2024-08-21 06:18:36 +02:00
parent 2138b3eed0
commit 1eaeade155
86 changed files with 1950 additions and 1499 deletions

View File

@ -0,0 +1,172 @@
package net.hostsharing.hsadminng.hs.booking.item;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import io.hypersistence.utils.hibernate.type.range.PostgreSQLRangeType;
import io.hypersistence.utils.hibernate.type.range.Range;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
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.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
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.PostLoad;
import jakarta.persistence.Transient;
import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static java.util.Collections.emptyMap;
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.stringify.Stringify.stringify;
@MappedSuperclass
@Getter
@Setter
@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<HsBookingItem> stringify = stringify(HsBookingItem.class)
.withProp(HsBookingItem::getType)
.withProp(HsBookingItem::getCaption)
.withProp(HsBookingItem::getProject)
.withProp(e -> e.getValidity().asString())
.withProp(HsBookingItem::getResources)
.quotedValues(false);
@Id
@GeneratedValue
private UUID uuid;
@Version
private int version;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "projectuuid")
private HsBookingProjectRealEntity project;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentitemuuid")
private HsBookingItemRealEntity parentItem;
@NotNull
@Column(name = "type")
@Enumerated(EnumType.STRING)
private HsBookingItemType type;
@Builder.Default
@Type(PostgreSQLRangeType.class)
@Column(name = "validity", columnDefinition = "daterange")
private Range<LocalDate> validity = Range.closedInfinite(LocalDate.now());
@Column(name = "caption")
private String caption;
@Builder.Default
@Setter(AccessLevel.NONE)
@Type(JsonType.class)
@Column(columnDefinition = "resources")
private Map<String, Object> resources = new HashMap<>();
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true)
@JoinColumn(name = "parentitemuuid", referencedColumnName = "uuid")
private List<HsBookingItemRealEntity> subBookingItems;
@Transient
private PatchableMapWrapper<Object> resourcesWrapper;
@Transient
private boolean isLoaded;
@PostLoad
public void markAsLoaded() {
this.isLoaded = true;
}
public PatchableMapWrapper<Object> getResources() {
return PatchableMapWrapper.of(resourcesWrapper, (newWrapper) -> {resourcesWrapper = newWrapper;}, resources);
}
public void putResources(Map<String, Object> newResources) {
getResources().assign(newResources);
}
public void setValidFrom(final LocalDate validFrom) {
setValidity(toPostgresDateRange(validFrom, getValidTo()));
}
public void setValidTo(final LocalDate validTo) {
setValidity(toPostgresDateRange(getValidFrom(), validTo));
}
public LocalDate getValidFrom() {
return lowerInclusiveFromPostgresDateRange(getValidity());
}
public LocalDate getValidTo() {
return upperInclusiveFromPostgresDateRange(getValidity());
}
@Override
public PatchableMapWrapper<Object> directProps() {
return getResources();
}
@Override
public Object getContextValue(final String propName) {
final var v = resources.get(propName);
if (v != null) {
return v;
}
if (parentItem != null) {
return parentItem.getResources().get(propName);
}
return emptyMap();
}
@Override
public String toString() {
return stringify.apply(this);
}
@Override
public String toShortString() {
return ofNullable(getRelatedProject()).map(HsBookingProject::toShortString).orElse("D-???????-?") +
":" + caption;
}
public HsBookingProject getRelatedProject() {
return project != null ? project
: parentItem != null ? parentItem.getRelatedProject()
: null; // can be the case for technical assets like IP-numbers
}
}

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

@ -1,241 +0,0 @@
package net.hostsharing.hsadminng.hs.booking.item;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import io.hypersistence.utils.hibernate.type.range.PostgreSQLRangeType;
import io.hypersistence.utils.hibernate.type.range.Range;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
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;
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;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
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;
import java.util.Map;
import java.util.UUID;
import static java.util.Collections.emptyMap;
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")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingItemEntity>, PropertiesProvider {
private static Stringify<HsBookingItemEntity> stringify = stringify(HsBookingItemEntity.class)
.withProp(HsBookingItemEntity::getType)
.withProp(HsBookingItemEntity::getCaption)
.withProp(HsBookingItemEntity::getProject)
.withProp(e -> e.getValidity().asString())
.withProp(HsBookingItemEntity::getResources)
.quotedValues(false);
@Id
@GeneratedValue
private UUID uuid;
@Version
private int version;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "projectuuid")
private HsBookingProjectEntity project;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentitemuuid")
private HsBookingItemEntity parentItem;
@NotNull
@Column(name = "type")
@Enumerated(EnumType.STRING)
private HsBookingItemType type;
@Builder.Default
@Type(PostgreSQLRangeType.class)
@Column(name = "validity", columnDefinition = "daterange")
private Range<LocalDate> validity = Range.closedInfinite(LocalDate.now());
@Column(name = "caption")
private String caption;
@Builder.Default
@Setter(AccessLevel.NONE)
@Type(JsonType.class)
@Column(columnDefinition = "resources")
private Map<String, Object> resources = new HashMap<>();
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true)
@JoinColumn(name="parentitemuuid", referencedColumnName="uuid")
private List<HsBookingItemEntity> subBookingItems;
@OneToOne(mappedBy="bookingItem")
private HsHostingAssetEntity relatedHostingAsset;
@Transient
private PatchableMapWrapper<Object> resourcesWrapper;
@Transient
private boolean isLoaded;
@PostLoad
public void markAsLoaded() {
this.isLoaded = true;
}
public PatchableMapWrapper<Object> getResources() {
return PatchableMapWrapper.of(resourcesWrapper, (newWrapper) -> {resourcesWrapper = newWrapper; }, resources );
}
public void putResources(Map<String, Object> newResources) {
getResources().assign(newResources);
}
public void setValidFrom(final LocalDate validFrom) {
setValidity(toPostgresDateRange(validFrom, getValidTo()));
}
public void setValidTo(final LocalDate validTo) {
setValidity(toPostgresDateRange(getValidFrom(), validTo));
}
public LocalDate getValidFrom() {
return lowerInclusiveFromPostgresDateRange(getValidity());
}
public LocalDate getValidTo() {
return upperInclusiveFromPostgresDateRange(getValidity());
}
@Override
public PatchableMapWrapper<Object> directProps() {
return getResources();
}
@Override
public Object getContextValue(final String propName) {
final var v = resources.get(propName);
if (v!= null) {
return v;
}
if (parentItem!=null) {
return parentItem.getResources().get(propName);
}
return emptyMap();
}
@Override
public String toString() {
return stringify.apply(this);
}
@Override
public String toShortString() {
return ofNullable(relatedProject()).map(HsBookingProjectEntity::toShortString).orElse("D-???????-?") +
":" + caption;
}
private HsBookingProjectEntity relatedProject() {
if (project != null) {
return project;
}
return parentItem == null ? null : parentItem.relatedProject();
}
public HsBookingProjectEntity 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", HsBookingProjectEntity.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

@ -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(
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));
() -> 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) {
// TODO.perf: maybe we need to cache the result at least for a single valiationrun
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

@ -1,6 +1,7 @@
package net.hostsharing.hsadminng.hs.booking.project;
import lombok.*;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
@ -27,18 +28,17 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder
@Entity
@Table(name = "hs_booking_project_rv")
@MappedSuperclass
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBookingProjectEntity> {
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder(builderMethodName = "baseBuilder", toBuilder = true)
public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBookingProject> {
private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class)
.withProp(HsBookingProjectEntity::getDebitor)
.withProp(HsBookingProjectEntity::getCaption)
private static Stringify<HsBookingProject> stringify = stringify(HsBookingProject.class)
.withProp(HsBookingProject::getDebitor)
.withProp(HsBookingProject::getCaption)
.quotedValues(false);
@Id
@ -67,7 +67,7 @@ public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBooki
}
public static RbacView rbac() {
return rbacViewFor("project", HsBookingProjectEntity.class)
return rbacViewFor("project", HsBookingProject.class)
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject

View File

@ -28,7 +28,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
private Mapper mapper;
@Autowired
private HsBookingProjectRepository bookingProjectRepo;
private HsBookingProjectRbacRepository bookingProjectRepo;
@Autowired
private HsBookingDebitorRepository debitorRepo;
@ -56,7 +56,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
context.define(currentUser, assumedRoles);
final var entityToSave = mapper.map(body, HsBookingProjectEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var entityToSave = mapper.map(body, HsBookingProjectRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var saved = bookingProjectRepo.save(entityToSave);
@ -118,7 +118,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
return ResponseEntity.ok(mapped);
}
final BiConsumer<HsBookingProjectInsertResource, HsBookingProjectEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
final BiConsumer<HsBookingProjectInsertResource, HsBookingProjectRbacEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
if (resource.getDebitorUuid() != null) {
entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] debitorUuid %s not found".formatted(

View File

@ -8,9 +8,9 @@ import net.hostsharing.hsadminng.mapper.OptionalFromJson;
public class HsBookingProjectEntityPatcher implements EntityPatcher<HsBookingProjectPatchResource> {
private final HsBookingProjectEntity entity;
private final HsBookingProject entity;
public HsBookingProjectEntityPatcher(final HsBookingProjectEntity entity) {
public HsBookingProjectEntityPatcher(final HsBookingProject entity) {
this.entity = entity;
}

View File

@ -0,0 +1,86 @@
package net.hostsharing.hsadminng.hs.booking.project;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import java.io.IOException;
import static net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType.DEBITOR;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.ColumnValue.usingDefaultCase;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NOT_NULL;
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.SQL.fetchedBySql;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_booking_project_rv")
@SuperBuilder(toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
public class HsBookingProjectRbacEntity extends HsBookingProject {
public static RbacView rbac() {
return rbacViewFor("project", HsBookingProjectRbacEntity.class)
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
"""))
.withRestrictedViewOrderBy(SQL.expression("caption"))
.withUpdatableColumns("version", "caption")
.importEntityAlias("debitor", HsOfficeDebitorEntity.class, usingDefaultCase(),
dependsOnColumn("debitorUuid"),
directlyFetchedByDependsOnColumn(),
NOT_NULL)
.importEntityAlias("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
dependsOnColumn("debitorUuid"),
fetchedBySql("""
SELECT ${columns}
FROM hs_office_relation debitorRel
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
WHERE debitor.uuid = ${REF}.debitorUuid
"""),
NOT_NULL)
.toRole("debitorRel", ADMIN).grantPermission(INSERT)
.toRole("global", ADMIN).grantPermission(DELETE)
.createRole(OWNER, (with) -> {
with.incomingSuperRole("debitorRel", AGENT).unassumed();
})
.createSubRole(ADMIN, (with) -> {
with.permission(UPDATE);
})
.createSubRole(AGENT)
.createSubRole(TENANT, (with) -> {
with.outgoingSubRole("debitorRel", TENANT);
with.permission(SELECT);
})
.limitDiagramTo("project", "debitorRel", "global");
}
public static void main(String[] args) throws IOException {
rbac().generateWithBaseFileName("6-hs-booking/620-booking-project/6203-hs-booking-project-rbac");
}
}

View File

@ -0,0 +1,22 @@
package net.hostsharing.hsadminng.hs.booking.project;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRbacRepository extends HsBookingProjectRepository<HsBookingProjectRbacEntity>,
Repository<HsBookingProjectRbacEntity, UUID> {
Optional<HsBookingProjectRbacEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectRbacEntity> findByCaption(final String projectCaption);
List<HsBookingProjectRbacEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
HsBookingProjectRbacEntity save(HsBookingProjectRbacEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -0,0 +1,19 @@
package net.hostsharing.hsadminng.hs.booking.project;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Table(name = "hs_booking_project")
@SuperBuilder(toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
public class HsBookingProjectRealEntity extends HsBookingProject {
}

View File

@ -0,0 +1,22 @@
package net.hostsharing.hsadminng.hs.booking.project;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRealRepository extends HsBookingProjectRepository<HsBookingProjectRealEntity>,
Repository<HsBookingProjectRealEntity, UUID> {
Optional<HsBookingProjectRealEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectRealEntity> findByCaption(final String projectCaption);
List<HsBookingProjectRealEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
HsBookingProjectRealEntity save(HsBookingProjectRealEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -1,19 +1,17 @@
package net.hostsharing.hsadminng.hs.booking.project;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsBookingProjectRepository extends Repository<HsBookingProjectEntity, UUID> {
public interface HsBookingProjectRepository<E extends HsBookingProject> {
Optional<HsBookingProjectEntity> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectEntity> findByCaption(final String projectCaption);
Optional<E> findByUuid(final UUID bookingProjectUuid);
List<E> findByCaption(final String projectCaption);
List<HsBookingProjectEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
List<E> findAllByDebitorUuid(final UUID bookingProjectUuid);
HsBookingProjectEntity save(HsBookingProjectEntity current);
E save(E current);
int deleteByUuid(final UUID uuid);

View File

@ -1,13 +1,40 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.Getter;
import lombok.experimental.SuperBuilder;
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;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable;
import org.hibernate.annotations.Type;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
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.Transient;
import jakarta.persistence.Version;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -16,9 +43,15 @@ import java.util.UUID;
import static java.util.Collections.emptyMap;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
public interface HsHostingAsset extends Stringifyable, BaseEntity<HsHostingAsset>, PropertiesProvider {
@MappedSuperclass
@Getter
@Setter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@SuperBuilder(builderMethodName = "baseBuilder", toBuilder = true)
public abstract class HsHostingAsset implements Stringifyable, BaseEntity<HsHostingAsset>, PropertiesProvider {
Stringify<HsHostingAsset> stringify = stringify(HsHostingAsset.class)
static Stringify<HsHostingAsset> stringify = stringify(HsHostingAsset.class)
.withProp(HsHostingAsset::getType)
.withProp(HsHostingAsset::getIdentifier)
.withProp(HsHostingAsset::getCaption)
@ -28,29 +61,83 @@ public interface HsHostingAsset extends Stringifyable, BaseEntity<HsHostingAsset
.withProp(HsHostingAsset::getConfig)
.quotedValues(false);
@Id
@GeneratedValue
private UUID uuid;
void setUuid(UUID uuid);
HsHostingAssetType getType();
HsHostingAsset getParentAsset();
void setIdentifier(String s);
String getIdentifier();
HsBookingItemEntity getBookingItem();
HsHostingAsset getAssignedToAsset();
HsOfficeContactRealEntity getAlarmContact();
List<? extends HsHostingAsset> getSubHostingAssets();
String getCaption();
Map<String, Object> getConfig();
@Version
private int version;
default HsBookingProjectEntity getRelatedProject() {
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "bookingitemuuid")
private HsBookingItemRealEntity bookingItem;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentassetuuid")
private HsHostingAssetRealEntity parentAsset;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "assignedtoassetuuid")
private HsHostingAssetRealEntity assignedToAsset;
@Column(name = "type")
@Enumerated(EnumType.STRING)
private HsHostingAssetType type;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "alarmcontactuuid")
private HsOfficeContactRealEntity alarmContact;
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "parentassetuuid", referencedColumnName = "uuid")
private List<HsHostingAssetRealEntity> subHostingAssets;
@Column(name = "identifier")
private String identifier; // e.g. vm1234, xyz00, example.org, xyz00_abc
@Column(name = "caption")
private String caption;
@Builder.Default
@Setter(AccessLevel.NONE)
@Type(JsonType.class)
@Column(columnDefinition = "config")
private Map<String, Object> config = new HashMap<>();
@Transient
private PatchableMapWrapper<Object> configWrapper;
@Transient
private boolean isLoaded;
@PostLoad
public void markAsLoaded() {
this.isLoaded = true;
}
public PatchableMapWrapper<Object> getConfig() {
return PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper;}, config);
}
public void putConfig(Map<String, Object> newConfig) {
PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper;}, config).assign(newConfig);
}
@Override
public PatchableMapWrapper<Object> directProps() {
return getConfig();
}
public HsBookingProject getRelatedProject() {
return Optional.ofNullable(getBookingItem())
.map(HsBookingItemEntity::getRelatedProject)
.map(HsBookingItem::getRelatedProject)
.orElseGet(() -> Optional.ofNullable(getParentAsset())
.map(HsHostingAsset::getRelatedProject)
.orElse(null));
}
@Override
default Object getContextValue(final String propName) {
public Object getContextValue(final String propName) {
final var v = directProps().get(propName);
if (v != null) {
return v;
@ -66,7 +153,12 @@ public interface HsHostingAsset extends Stringifyable, BaseEntity<HsHostingAsset
}
@Override
default String toShortString() {
public String toShortString() {
return getType() + ":" + getIdentifier();
}
@Override
public String toString() {
return stringify.apply(this);
}
}

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,10 +39,13 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
private Mapper mapper;
@Autowired
private HsHostingAssetRepository assetRepo;
private HsHostingAssetRbacRepository rbacAssetRepo;
@Autowired
private HsBookingItemRepository bookingItemRepo;
private HsHostingAssetRealRepository realAssetRepo;
@Autowired
private HsBookingItemRealRepository realBookingItemRepo;
@Override
@Transactional(readOnly = true)
@ -54,7 +57,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final HsHostingAssetTypeResource type) {
context.define(currentUser, assumedRoles);
final var entities = assetRepo.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);
@ -70,13 +73,13 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
context.define(currentUser, assumedRoles);
final var entity = mapper.map(body, HsHostingAssetEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var entity = mapper.map(body, HsHostingAssetRbacEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
final var mapped = new HostingAssetEntitySaveProcessor(em, entity)
.preprocessEntity()
.validateEntity()
.prepareForSave()
.saveUsing(assetRepo::save)
.saveUsing(rbacAssetRepo::save)
.validateContext()
.mapUsing(e -> mapper.map(e, HsHostingAssetResource.class))
.revampProperties();
@ -98,7 +101,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
context.define(currentUser, assumedRoles);
final var result = assetRepo.findByUuid(assetUuid);
final var result = rbacAssetRepo.findByUuid(assetUuid);
return result
.map(assetEntity -> ResponseEntity.ok(
mapper.map(assetEntity, HsHostingAssetResource.class, ENTITY_TO_RESOURCE_POSTMAPPER)))
@ -113,7 +116,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
final UUID assetUuid) {
context.define(currentUser, assumedRoles);
final var result = assetRepo.deleteByUuid(assetUuid);
final var result = rbacAssetRepo.deleteByUuid(assetUuid);
return result == 0
? ResponseEntity.notFound().build()
: ResponseEntity.noContent().build();
@ -129,7 +132,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
context.define(currentUser, assumedRoles);
final var entity = assetRepo.findByUuid(assetUuid).orElseThrow();
final var entity = rbacAssetRepo.findByUuid(assetUuid).orElseThrow();
new HsHostingAssetEntityPatcher(em, entity).apply(body);
@ -137,7 +140,7 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
.preprocessEntity()
.validateEntity()
.prepareForSave()
.saveUsing(assetRepo::save)
.saveUsing(rbacAssetRepo::save)
.validateContext()
.mapUsing(e -> mapper.map(e, HsHostingAssetResource.class))
.revampProperties();
@ -145,22 +148,22 @@ public class HsHostingAssetController implements HsHostingAssetsApi {
return ResponseEntity.ok(mapped);
}
final BiConsumer<HsHostingAssetInsertResource, HsHostingAssetEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
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(realBookingItemRepo.findByUuid(resource.getBookingItemUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] bookingItemUuid %s not found".formatted(
resource.getBookingItemUuid()))));
}
if (resource.getParentAssetUuid() != null) {
entity.setParentAsset(assetRepo.findByUuid(resource.getParentAssetUuid())
entity.setParentAsset(realAssetRepo.findByUuid(resource.getParentAssetUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] parentAssetUuid %s not found".formatted(
resource.getParentAssetUuid()))));
}
};
@SuppressWarnings("unchecked")
final BiConsumer<HsHostingAssetEntity, HsHostingAssetResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource)
final BiConsumer<HsHostingAssetRbacEntity, HsHostingAssetResource> ENTITY_TO_RESOURCE_POSTMAPPER = (entity, resource)
-> resource.setConfig(HostingAssetEntityValidatorRegistry.forType(entity.getType())
.revampProperties(em, entity, (Map<String, Object>) resource.getConfig()));
}

View File

@ -12,9 +12,9 @@ import java.util.Optional;
public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAssetPatchResource> {
private final EntityManager em;
private final HsHostingAssetEntity entity;
private final HsHostingAssetRbacEntity entity;
public HsHostingAssetEntityPatcher(final EntityManager em, final HsHostingAssetEntity entity) {
public HsHostingAssetEntityPatcher(final EntityManager em, final HsHostingAssetRbacEntity entity) {
this.em = em;
this.entity = entity;
}

View File

@ -1,41 +1,17 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
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;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
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 java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.CaseDef.inCaseOf;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
@ -56,106 +32,33 @@ 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;
@Builder
@Entity
@Table(name = "hs_hosting_asset_rv")
@SuperBuilder(toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class HsHostingAssetEntity implements HsHostingAsset {
@Id
@GeneratedValue
private UUID uuid;
@Version
private int version;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "bookingitemuuid")
private HsBookingItemEntity bookingItem;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentassetuuid")
private HsHostingAssetEntity parentAsset;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "assignedtoassetuuid")
private HsHostingAssetEntity assignedToAsset;
@Column(name = "type")
@Enumerated(EnumType.STRING)
private HsHostingAssetType type;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "alarmcontactuuid")
private HsOfficeContactRealEntity alarmContact;
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "parentassetuuid", referencedColumnName = "uuid")
private List<HsHostingAssetEntity> subHostingAssets;
@Column(name = "identifier")
private String identifier; // e.g. vm1234, xyz00, example.org, xyz00_abc
@Column(name = "caption")
private String caption;
@Builder.Default
@Setter(AccessLevel.NONE)
@Type(JsonType.class)
@Column(columnDefinition = "config")
private Map<String, Object> config = new HashMap<>();
@Transient
private PatchableMapWrapper<Object> configWrapper;
@Transient
private boolean isLoaded;
@PostLoad
public void markAsLoaded() {
this.isLoaded = true;
}
public PatchableMapWrapper<Object> getConfig() {
return PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper;}, config);
}
public void putConfig(Map<String, Object> newConfig) {
PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper;}, config).assign(newConfig);
}
@Override
public PatchableMapWrapper<Object> directProps() {
return getConfig();
}
@Override
public String toString() {
return stringify.using(HsHostingAssetEntity.class).apply(this);
}
public class HsHostingAssetRbacEntity extends HsHostingAsset {
public static RbacView rbac() {
return rbacViewFor("asset", HsHostingAssetEntity.class)
return rbacViewFor("asset", HsHostingAssetRbacEntity.class)
.withIdentityView(SQL.projection("identifier"))
.withRestrictedViewOrderBy(SQL.expression("identifier"))
.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)
.importEntityAlias("parentAsset", HsHostingAssetEntity.class, usingDefaultCase(),
.importEntityAlias("parentAsset", HsHostingAssetRbacEntity.class, usingDefaultCase(),
dependsOnColumn("parentAssetUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
.toRole("parentAsset", ADMIN).grantPermission(INSERT)
.importEntityAlias("assignedToAsset", HsHostingAssetEntity.class, usingDefaultCase(),
.importEntityAlias("assignedToAsset", HsHostingAssetRbacEntity.class, usingDefaultCase(),
dependsOnColumn("assignedToAssetUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)

View File

@ -0,0 +1,47 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsHostingAssetRbacRepository extends HsHostingAssetRepository<HsHostingAssetRbacEntity>, Repository<HsHostingAssetRbacEntity, UUID> {
Optional<HsHostingAssetRbacEntity> findByUuid(final UUID serverUuid);
List<HsHostingAssetRbacEntity> findByIdentifier(String assetIdentifier);
@Query(value = """
select ha.uuid,
ha.alarmcontactuuid,
ha.assignedtoassetuuid,
ha.bookingitemuuid,
ha.caption,
ha.config,
ha.identifier,
ha.parentassetuuid,
ha.type,
ha.version
from hs_hosting_asset_rv ha
left join hs_booking_item bi on bi.uuid = ha.bookingitemuuid
left join hs_hosting_asset pha on pha.uuid = ha.parentassetuuid
where (:projectUuid is null or bi.projectuuid=:projectUuid)
and (:parentAssetUuid is null or pha.uuid=:parentAssetUuid)
and (:type is null or :type=cast(ha.type as text))
""", nativeQuery = true)
// The JPQL query did not generate "left join" but just "join".
// I also optimized the query by not using the _rv for hs_booking_item and hs_hosting_asset, only for hs_hosting_asset_rv.
List<HsHostingAssetRbacEntity> findAllByCriteriaImpl(UUID projectUuid, UUID parentAssetUuid, String type);
default List<HsHostingAssetRbacEntity> findAllByCriteria(final UUID projectUuid, final UUID parentAssetUuid, final HsHostingAssetType type) {
return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type));
}
HsHostingAssetRbacEntity save(HsHostingAsset current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -0,0 +1,24 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Table(name = "hs_hosting_asset")
@SuperBuilder(builderMethodName = "genericBuilder", toBuilder = true)
@Getter
@Setter
@NoArgsConstructor
public class HsHostingAssetRealEntity extends HsHostingAsset {
// without this wrapper method, the builder returns a generic entity which cannot resolved in a generic context
public static HsHostingAssetRealEntityBuilder<HsHostingAssetRealEntity, ?> builder() {
//noinspection unchecked
return (HsHostingAssetRealEntityBuilder<HsHostingAssetRealEntity, ?>) genericBuilder();
}
}

View File

@ -0,0 +1,46 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsHostingAssetRealRepository extends HsHostingAssetRepository<HsHostingAssetRealEntity>, Repository<HsHostingAssetRealEntity, UUID> {
Optional<HsHostingAssetRealEntity> findByUuid(final UUID serverUuid);
List<HsHostingAssetRealEntity> findByIdentifier(String assetIdentifier);
@Query(value = """
select ha.uuid,
ha.alarmcontactuuid,
ha.assignedtoassetuuid,
ha.bookingitemuuid,
ha.caption,
ha.config,
ha.identifier,
ha.parentassetuuid,
ha.type,
ha.version
from hs_hosting_asset_rv ha
left join hs_booking_item bi on bi.uuid = ha.bookingitemuuid
left join hs_hosting_asset pha on pha.uuid = ha.parentassetuuid
where (:projectUuid is null or bi.projectuuid=:projectUuid)
and (:parentAssetUuid is null or pha.uuid=:parentAssetUuid)
and (:type is null or :type=cast(ha.type as text))
""", nativeQuery = true)
// The JPQL query did not generate "left join" but just "join".
// I also optimized the query by not using the _rv for hs_booking_item and hs_hosting_asset, only for hs_hosting_asset_rv.
List<HsHostingAssetRealEntity> findAllByCriteriaImpl(UUID projectUuid, UUID parentAssetUuid, String type);
default List<HsHostingAssetRealEntity> findAllByCriteria(final UUID projectUuid, final UUID parentAssetUuid, final HsHostingAssetType type) {
return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type));
}
HsHostingAssetRealEntity save(HsHostingAssetRealEntity current);
int deleteByUuid(final UUID uuid);
long count();
}

View File

@ -1,45 +1,22 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface HsHostingAssetRepository<E extends HsHostingAsset> {
public interface HsHostingAssetRepository extends Repository<HsHostingAssetEntity, UUID> {
Optional<E> findByUuid(final UUID serverUuid);
Optional<HsHostingAssetEntity> findByUuid(final UUID serverUuid);
List<E> findByIdentifier(String assetIdentifier);
List<HsHostingAssetEntity> findByIdentifier(String assetIdentifier);
List<E> findAllByCriteriaImpl(UUID projectUuid, UUID parentAssetUuid, String type);
@Query(value = """
select ha.uuid,
ha.alarmcontactuuid,
ha.assignedtoassetuuid,
ha.bookingitemuuid,
ha.caption,
ha.config,
ha.identifier,
ha.parentassetuuid,
ha.type,
ha.version
from hs_hosting_asset_rv ha
left join hs_booking_item bi on bi.uuid = ha.bookingitemuuid
left join hs_hosting_asset pha on pha.uuid = ha.parentassetuuid
where (:projectUuid is null or bi.projectuuid=:projectUuid)
and (:parentAssetUuid is null or pha.uuid=:parentAssetUuid)
and (:type is null or :type=cast(ha.type as text))
""", nativeQuery = true)
// The JPQL query did not generate "left join" but just "join".
// I also optimized the query by not using the _rv for hs_booking_item and hs_hosting_asset, only for hs_hosting_asset_rv.
List<HsHostingAssetEntity> findAllByCriteriaImpl(UUID projectUuid, UUID parentAssetUuid, String type);
default List<HsHostingAssetEntity> findAllByCriteria(final UUID projectUuid, final UUID parentAssetUuid, final HsHostingAssetType type) {
default List<E> findAllByCriteria(final UUID projectUuid, final UUID parentAssetUuid, final HsHostingAssetType type) {
return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type));
}
HsHostingAssetEntity save(HsHostingAsset current);
E save(HsHostingAsset current);
int deleteByUuid(final UUID uuid);

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;
@ -354,14 +354,14 @@ class EntityTypeRelation<E, T extends Node> {
final HsHostingAssetType.RelationPolicy relationPolicy;
final HsHostingAssetType.RelationType relationType;
final Function<HsHostingAssetEntity, E> getter;
final Function<HsHostingAssetRbacEntity, E> getter;
private final List<T> acceptedRelatedTypes;
final String edge;
private EntityTypeRelation(
final HsHostingAssetType.RelationPolicy relationPolicy,
final HsHostingAssetType.RelationType relationType,
final Function<HsHostingAssetEntity, E> getter,
final Function<HsHostingAssetRbacEntity, E> getter,
final T acceptedRelatedType,
final String edge
) {
@ -376,11 +376,11 @@ 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,
HsHostingAssetEntity::getBookingItem,
HsHostingAssetRbacEntity::getBookingItem,
bookingItemType,
" *==> ");
}

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");
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,15 @@ 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();
} finally {
localEntityManager.remove();
}
}
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

@ -4,6 +4,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
@ -24,6 +25,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class TestCustomerEntity implements BaseEntity<TestCustomerEntity> {
@Id

View File

@ -1,6 +1,9 @@
package net.hostsharing.hsadminng.arch;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaMethod;
import com.tngtech.archunit.core.domain.JavaModifier;
import com.tngtech.archunit.junit.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchCondition;
@ -8,11 +11,10 @@ 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.hosting.asset.HsHostingAssetEntity;
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;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import org.springframework.data.repository.Repository;
import org.springframework.web.bind.annotation.RestController;
@ -328,8 +330,8 @@ public class ArchitectureTest {
ContextBasedTest.class,
RbacGrantsDiagramService.class)
.ignoreDependency(
HsBookingItemEntity.class,
HsHostingAssetEntity.class);
HsBookingItem.class,
HsHostingAssetRbacEntity.class);
@ArchTest
@ -347,10 +349,21 @@ public class ArchitectureTest {
static final ArchRule tableNamesOfRbacEntitiesShouldEndWith_rv =
classes()
.that().areAnnotatedWith(Table.class)
.and().areAssignableTo(BaseEntity.class)
.and().containAnyMethodsThat(hasStaticMethodNamed("rbac"))
// .and().haveNameNotMatching(".*RealEntity") TODO.test: check rules for RealEntity vs. RbacEntity
.should(haveTableNameEndingWith_rv())
.because("it's required that the table names of RBAC entities end with '_rv'");
private static DescribedPredicate<JavaMethod> hasStaticMethodNamed(final String expectedName) {
return new DescribedPredicate<>("rbac entity") {
@Override
public boolean test(final JavaMethod method) {
return method.getModifiers().contains(JavaModifier.STATIC) && method.getName().equals(expectedName);
}
};
}
static ArchCondition<JavaClass> haveTableNameEndingWith_rv() {
return new ArchCondition<>("RBAC table name end with _rv") {

View File

@ -4,7 +4,7 @@ import io.hypersistence.utils.hibernate.type.range.Range;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
@ -44,10 +44,10 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
private Integer port;
@Autowired
HsBookingItemRepository bookingItemRepo;
HsBookingItemRealRepository realBookingItemRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@ -65,7 +65,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
// given
context("superuser-alex@hostsharing.net");
final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.findFirst()
.orElseThrow();
@ -133,7 +133,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
context.define("superuser-alex@hostsharing.net");
final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.findFirst()
.orElseThrow();
@ -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 = projectRepo.findByCaption(projectCaption).stream()
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

@ -1,8 +1,8 @@
package net.hostsharing.hsadminng.hs.booking.item;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.mapper.Mapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
@ -51,10 +51,10 @@ class HsBookingItemControllerRestTest {
EntityManagerFactory emf;
@MockBean
HsBookingProjectRepository bookingProjectRepo;
HsBookingProjectRealRepository realProjectRepo;
@MockBean
HsBookingItemRepository bookingItemRepo;
HsBookingItemRbacRepository rbacBookingItemRepo;
@BeforeEach
void init() {
@ -73,12 +73,12 @@ class HsBookingItemControllerRestTest {
final var givenProjectUuid = UUID.randomUUID();
// given
when(em.find(HsBookingProjectEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectEntity.builder()
when(em.find(HsBookingProjectRealEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectRealEntity.builder()
.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
@ -123,12 +123,12 @@ class HsBookingItemControllerRestTest {
final var givenProjectUuid = UUID.randomUUID();
// given
when(em.find(HsBookingProjectEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectEntity.builder()
when(em.find(HsBookingProjectRealEntity.class, givenProjectUuid)).thenAnswer(invocation ->
HsBookingProjectRealEntity.builder()
.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

@ -17,7 +17,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.stream.Stream;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_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;
@ -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,15 +62,15 @@ 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(TEST_PROJECT);
entity.setProject(PROJECT_TEST_ENTITY);
entity.getResources().putAll(KeyValueMap.from(INITIAL_RESOURCES));
entity.setCaption(INITIAL_CAPTION);
entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));
@ -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

@ -10,7 +10,7 @@ import java.time.Month;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
import static net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
import static org.assertj.core.api.Assertions.assertThat;
@ -20,8 +20,8 @@ class HsBookingItemEntityUnitTest {
private MockedStatic<LocalDate> localDateMockedStatic = Mockito.mockStatic(LocalDate.class, Mockito.CALLS_REAL_METHODS);
final HsBookingItemEntity givenBookingItem = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
final HsBookingItem givenBookingItem = HsBookingItemRbacEntity.builder()
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.CLOUD_SERVER)
.caption("some caption")
.resources(Map.ofEntries(
@ -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

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item;
import io.hypersistence.utils.hibernate.type.range.Range;
import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
@ -39,10 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired
HsBookingItemRepository bookingItemRepo;
HsBookingItemRbacRepository rbacBookingItemRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@ -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 = projectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).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
@ -102,15 +102,15 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when
attempt(em, () -> {
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0);
final var givenProject = projectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
final var newBookingItem = HsBookingItemEntity.builder()
final var givenProject = realProjectRepo.findAllByDebitorUuid(givenDebitor.getUuid()).get(0);
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());
}
}
@ -160,22 +160,19 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// given
context("superuser-alex@hostsharing.net");
final var projectUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.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
@ -185,19 +182,19 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
final var debitor = debitorRepo.findDebitorByDebitorNumber(1000111);
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:OWNER");
final var projectUuid = debitor.stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid()))
.map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream)
.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
@ -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 = projectRepo.findByCaption(projectCaption).stream()
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

@ -7,13 +7,13 @@ import java.time.LocalDate;
import java.util.Map;
import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
@UtilityClass
public class TestHsBookingItem {
public static final HsBookingItemEntity TEST_CLOUD_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
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")
.resources(Map.ofEntries(
@ -25,8 +25,8 @@ public class TestHsBookingItem {
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
.build();
public static final HsBookingItemEntity TEST_MANAGED_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
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")
.resources(Map.ofEntries(
@ -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.project.HsBookingProjectEntity;
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;
@ -18,22 +19,24 @@ class HsBookingItemEntityValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor)
.caption("test project")
.build();
private EntityManager em;
@Test
void validThrowsException() {
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.project.HsBookingProjectEntity;
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;
@ -20,15 +21,16 @@ class HsCloudServerBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.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.hosting.asset.EntityManagerMock;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
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,18 +20,20 @@ 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.hosting.asset.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()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor)
.caption("Test-Project")
.build();
@ -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(HsHostingAssetEntity.builder()
.build();
final var em = createEntityManagerMockWithAssetQueryFake(HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("abc00")
.subHostingAssets(concat(
@ -158,12 +167,10 @@ class HsManagedServerBookingItemValidatorUnitTest {
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(
@ -175,30 +182,30 @@ class HsManagedServerBookingItemValidatorUnitTest {
}
@SafeVarargs
private List<HsHostingAssetEntity> concat(final List<HsHostingAssetEntity>... hostingAssets) {
private List<HsHostingAssetRealEntity> concat(final List<HsHostingAssetRealEntity>... hostingAssets) {
return stream(hostingAssets)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
private List<HsHostingAssetEntity> generate(final int count, final HsHostingAssetType hostingAssetType,
private List<HsHostingAssetRealEntity> generate(final int count, final HsHostingAssetType hostingAssetType,
final String identifierPattern) {
return IntStream.range(0, count)
.mapToObj(number -> HsHostingAssetEntity.builder()
.mapToObj(number -> (HsHostingAssetRealEntity) HsHostingAssetRealEntity.builder()
.type(hostingAssetType)
.identifier(identifierPattern.formatted((number/'a')+'a', (number%'a')+'a'))
.build())
.toList();
}
private List<HsHostingAssetEntity> generateDbUsersWithDatabases(
private List<HsHostingAssetRealEntity> generateDbUsersWithDatabases(
final int userCount,
final HsHostingAssetType directAssetType,
final String directAssetIdentifierFormat,
final int dbCount,
final HsHostingAssetType subAssetType) {
return IntStream.range(0, userCount)
.mapToObj(n -> HsHostingAssetEntity.builder()
final List<HsHostingAssetRealEntity> list = IntStream.range(0, userCount)
.mapToObj(n -> HsHostingAssetRealEntity.builder()
.type(directAssetType)
.identifier(directAssetIdentifierFormat.formatted((n / 'a') + 'a', (n % 'a') + 'a'))
.subHostingAssets(
@ -206,16 +213,17 @@ class HsManagedServerBookingItemValidatorUnitTest {
)
.build())
.toList();
return list;
}
private List<HsHostingAssetEntity> generateDomainEmailSetupsWithEMailAddresses(
private List<HsHostingAssetRealEntity> generateDomainEmailSetupsWithEMailAddresses(
final int domainCount,
final HsHostingAssetType directAssetType,
final String directAssetIdentifierFormat,
final int emailAddressCount,
final HsHostingAssetType subAssetType) {
return IntStream.range(0, domainCount)
.mapToObj(n -> HsHostingAssetEntity.builder()
.mapToObj(n -> HsHostingAssetRealEntity.builder()
.type(directAssetType)
.identifier(directAssetIdentifierFormat.formatted((n/'a')+'a', (n%'a')+'a'))
.subHostingAssets(

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.project.HsBookingProjectEntity;
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;
@ -16,15 +17,16 @@ class HsManagedWebspaceBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.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,17 +1,19 @@
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.project.HsBookingProjectEntity;
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;
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.PRIVATE_CLOUD;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
import static org.assertj.core.api.Assertions.assertThat;
class HsPrivateCloudBookingItemValidatorUnitTest {
@ -19,17 +21,18 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345)
.build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder()
final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.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(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.caption("myPC")
.resources(ofEntries(
entry("CPU", 4),
@ -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

@ -32,10 +32,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
private Integer port;
@Autowired
HsBookingProjectRepository bookingProjectRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsBookingDebitorRepository debitorRepo;
@ -126,7 +123,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
@Test
void globalAdmin_canGetArbitraryBookingProject() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000111 default project").stream()
final var givenBookingProjectUuid = realProjectRepo.findByCaption("D-1000111 default project").stream()
.findAny().orElseThrow().getUuid();
RestAssured // @formatter:off
@ -148,8 +145,8 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
@Test
void normalUser_canNotGetUnrelatedBookingProject() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000212 default project").stream()
.map(HsBookingProjectEntity::getUuid)
final var givenBookingProjectUuid = realProjectRepo.findByCaption("D-1000212 default project").stream()
.map(HsBookingProject::getUuid)
.findAny().orElseThrow();
RestAssured // @formatter:off
@ -165,7 +162,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
@Test
void projectAgentUser_canGetRelatedBookingProject() {
context.define("superuser-alex@hostsharing.net");
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000313 default project").stream()
final var givenBookingProjectUuid = realProjectRepo.findByCaption("D-1000313 default project").stream()
.findAny().orElseThrow().getUuid();
RestAssured // @formatter:off
@ -217,7 +214,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
// finally, the bookingProject is actually updated
context.define("superuser-alex@hostsharing.net");
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get()
assertThat(realProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get()
.matches(mandate -> {
assertThat(mandate.getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)");
return true;
@ -243,7 +240,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
.statusCode(204); // @formatter:on
// then the given bookingProject is gone
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isEmpty();
assertThat(realProjectRepo.findByUuid(givenBookingProject.getUuid())).isEmpty();
}
@Test
@ -261,21 +258,21 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
.statusCode(404); // @formatter:on
// then the given bookingProject is still there
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isNotEmpty();
assertThat(realProjectRepo.findByUuid(givenBookingProject.getUuid())).isNotEmpty();
}
}
private HsBookingProjectEntity givenSomeBookingProject(final int debitorNumber, final String caption) {
private HsBookingProjectRealEntity givenSomeBookingProject(final int debitorNumber, final String caption) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow();
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRealEntity.builder()
.uuid(UUID.randomUUID())
.debitor(givenDebitor)
.caption(caption)
.build();
return bookingProjectRepo.save(newBookingProject);
return realProjectRepo.save(newBookingProject);
}).assertSuccessful().returnedValue();
}
}

View File

@ -23,7 +23,7 @@ import static org.mockito.Mockito.lenient;
@ExtendWith(MockitoExtension.class)
class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
HsBookingProjectPatchResource,
HsBookingProjectEntity
HsBookingProject
> {
private static final UUID INITIAL_BOOKING_PROJECT_UUID = UUID.randomUUID();
@ -38,13 +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());
lenient().when(em.getReference(eq(HsBookingProjectEntity.class), any())).thenAnswer(invocation ->
HsBookingProjectEntity.builder().uuid(invocation.getArgument(1)).build());
}
@Override
protected HsBookingProjectEntity newInitialEntity() {
final var entity = new HsBookingProjectEntity();
protected HsBookingProject newInitialEntity() {
final var entity = new HsBookingProjectRbacEntity();
entity.setUuid(INITIAL_BOOKING_PROJECT_UUID);
entity.setDebitor(TEST_BOOKING_DEBITOR);
entity.setCaption(INITIAL_CAPTION);
@ -57,7 +55,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
}
@Override
protected HsBookingProjectEntityPatcher createPatcher(final HsBookingProjectEntity bookingProject) {
protected HsBookingProjectEntityPatcher createPatcher(final HsBookingProject bookingProject) {
return new HsBookingProjectEntityPatcher(bookingProject);
}
@ -68,7 +66,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
"caption",
HsBookingProjectPatchResource::setCaption,
PATCHED_CAPTION,
HsBookingProjectEntity::setCaption)
HsBookingProject::setCaption)
);
}
}

View File

@ -2,26 +2,22 @@ package net.hostsharing.hsadminng.hs.booking.project;
import org.junit.jupiter.api.Test;
import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
import static org.assertj.core.api.Assertions.assertThat;
class HsBookingProjectEntityUnitTest {
final HsBookingProjectEntity givenBookingProject = HsBookingProjectEntity.builder()
.debitor(TEST_BOOKING_DEBITOR)
.caption("some caption")
.build();
@Test
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
final var result = givenBookingProject.toString();
final var result = PROJECT_TEST_ENTITY.toString();
assertThat(result).isEqualTo("HsBookingProjectEntity(D-1234500, some caption)");
assertThat(result).isEqualTo("HsBookingProject(D-1234500, test project)");
}
@Test
void toShortStringContainsOnlyMemberNumberAndCaption() {
final var result = givenBookingProject.toShortString();
final var result = PROJECT_TEST_ENTITY.toShortString();
assertThat(result).isEqualTo("D-1234500:some caption");
assertThat(result).isEqualTo("D-1234500:test project");
}
}

View File

@ -9,6 +9,8 @@ import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
@ -32,10 +34,10 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired
HsBookingProjectRepository bookingProjectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRbacRepository rbacProjectRepo;
@Autowired
HsBookingDebitorRepository debitorRepo;
@ -61,24 +63,24 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
@Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject() {
// given
context("superuser-alex@hostsharing.net");
final var count = bookingProjectRepo.count();
context("superuser-alex@hostsharing.net"); // TODO.test: remove once we have a realDebitorRepo
final var count = realProjectRepo.count();
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
// when
final var result = attempt(em, () -> {
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRbacEntity.builder()
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(bookingProjectRepo.save(newBookingProject));
return toCleanup(rbacProjectRepo.save(newBookingProject));
});
// then
result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingProjectEntity::getUuid).isNotNull();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingProject::getUuid).isNotNull();
assertThatBookingProjectIsPersisted(result.returnedValue());
assertThat(bookingProjectRepo.count()).isEqualTo(count + 1);
assertThat(realProjectRepo.count()).isEqualTo(count + 1);
}
@Test
@ -93,11 +95,11 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
attempt(em, () -> {
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRbacEntity.builder()
.debitor(givenDebitor)
.caption("some new booking project")
.build();
return toCleanup(bookingProjectRepo.save(newBookingProject));
return toCleanup(rbacProjectRepo.save(newBookingProject));
});
// then
@ -135,33 +137,35 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
null));
}
private void assertThatBookingProjectIsPersisted(final HsBookingProjectEntity saved) {
final var found = bookingProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingProjectEntity::toString).get().isEqualTo(saved.toString());
private void assertThatBookingProjectIsPersisted(final HsBookingProject saved) {
final var found = rbacProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingProject::toString).get().isEqualTo(saved.toString());
}
}
@Nested
class FindByDebitorUuid {
@Test
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net");
final var debitorUuid = debitorRepo.findByDebitorNumber(1000212).stream()
.findAny().orElseThrow().getUuid();
// when
final var result = bookingProjectRepo.findAllByDebitorUuid(debitorUuid);
final var result = repoUnderTest(testCase).findAllByDebitorUuid(debitorUuid);
// then
allTheseBookingProjectsAreReturned(
result,
"HsBookingProjectEntity(D-1000212, D-1000212 default project)");
"HsBookingProject(D-1000212, D-1000212 default project)");
}
@Test
public void packetAgent_canViewOnlyRelatedBookingProjects() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void packetAgent_canViewOnlyRelatedBookingProjects(final TestCase testCase) {
// given:
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
@ -169,50 +173,52 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
.findAny().orElseThrow().getUuid();
// when:
final var result = bookingProjectRepo.findAllByDebitorUuid(debitorUuid);
final var result = repoUnderTest(testCase).findAllByDebitorUuid(debitorUuid);
// then:
exactlyTheseBookingProjectsAreReturned(
result,
"HsBookingProjectEntity(D-1000111, D-1000111 default project)");
assertResult(testCase, result,
"HsBookingProject(D-1000111, D-1000111 default project)");
}
}
@Nested
class UpdateBookingProject {
@Test
public void hostsharingAdmin_canUpdateArbitraryBookingProject() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void bookingProjectAdmin_canUpdateArbitraryBookingProject(final TestCase testCase) {
// given
final var givenBookingProjectUuid = givenSomeTemporaryBookingProject(1000111).getUuid();
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var foundBookingProject = em.find(HsBookingProjectEntity.class, givenBookingProjectUuid);
return toCleanup(bookingProjectRepo.save(foundBookingProject));
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-sometempproject:ADMIN");
final var foundBookingProject = em.find(HsBookingProjectRbacEntity.class, givenBookingProjectUuid);
foundBookingProject.setCaption("updated caption");
return toCleanup(repoUnderTest(testCase).save(foundBookingProject));
});
// then
result.assertSuccessful();
jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
assertThat(result.returnedValue().getCaption()).isEqualTo("updated caption");
assertThatBookingProjectActuallyInDatabase(result.returnedValue());
}).assertSuccessful();
}
private void assertThatBookingProjectActuallyInDatabase(final HsBookingProjectEntity saved) {
final var found = bookingProjectRepo.findByUuid(saved.getUuid());
private void assertThatBookingProjectActuallyInDatabase(final HsBookingProject saved) {
jpaAttempt.transacted(() -> {
final var found = realProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved)
.extracting(Object::toString).isEqualTo(saved.toString());
}).assertSuccessful();
}
}
@Nested
class DeleteByUuid {
@Test
public void globalAdmin_withoutAssumedRole_canDeleteAnyBookingProject() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canDeleteAnyBookingProject(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net", null);
final var givenBookingProject = givenSomeTemporaryBookingProject(1000111);
@ -220,14 +226,14 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid());
repoUnderTest(testCase).deleteByUuid(givenBookingProject.getUuid());
});
// then
result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null);
return bookingProjectRepo.findByUuid(givenBookingProject.getUuid());
return rbacProjectRepo.findByUuid(givenBookingProject.getUuid());
}).assertSuccessful().returnedValue()).isEmpty();
}
@ -239,9 +245,9 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-sometempproject:AGENT");
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent();
assertThat(rbacProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent();
bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid());
repoUnderTest(TestCase.RBAC).deleteByUuid(givenBookingProject.getUuid());
});
// then
@ -250,12 +256,13 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
"[403] Subject ", " is not allowed to delete hs_booking_project");
assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return bookingProjectRepo.findByUuid(givenBookingProject.getUuid());
return rbacProjectRepo.findByUuid(givenBookingProject.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there
}
@Test
public void deletingABookingProjectAlsoDeletesRelatedRolesAndGrants() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void deletingABookingProjectAlsoDeletesRelatedRolesAndGrants(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
@ -265,7 +272,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid());
return repoUnderTest(testCase).deleteByUuid(givenBookingProject.getUuid());
});
// then
@ -295,32 +302,78 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
"[creating booking-project test-data 1000313, hs_booking_project, INSERT]");
}
private HsBookingProjectEntity givenSomeTemporaryBookingProject(final int debitorNumber) {
private HsBookingProjectRealEntity givenSomeTemporaryBookingProject(final int debitorNumber) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).get(0);
final var newBookingProject = HsBookingProjectEntity.builder()
final var newBookingProject = HsBookingProjectRealEntity.builder()
.debitor(givenDebitor)
.caption("some temp project")
.build();
return toCleanup(bookingProjectRepo.save(newBookingProject));
return toCleanup(realProjectRepo.save(newBookingProject));
}).assertSuccessful().returnedValue();
}
void exactlyTheseBookingProjectsAreReturned(
final List<HsBookingProjectEntity> actualResult,
final List<? extends HsBookingProject> actualResult,
final String... bookingProjectNames) {
assertThat(actualResult)
.extracting(HsBookingProjectEntity::toString)
.extracting(HsBookingProject::toString)
.containsExactlyInAnyOrder(bookingProjectNames);
}
void allTheseBookingProjectsAreReturned(
final List<HsBookingProjectEntity> actualResult,
final List<? extends HsBookingProject> actualResult,
final String... bookingProjectNames) {
assertThat(actualResult)
.extracting(HsBookingProjectEntity::toString)
.extracting(HsBookingProject::toString)
.contains(bookingProjectNames);
}
private HsBookingProjectRepository repoUnderTest(final TestCase testCase) {
return testCase.repo(HsBookingProjectRepositoryIntegrationTest.this);
}
private void assertResult(
final TestCase testCase,
final List<? extends HsBookingProject> actualResult,
final String... expectedProjects) {
testCase.assertResult(HsBookingProjectRepositoryIntegrationTest.this, actualResult, expectedProjects);
}
enum TestCase {
REAL {
@Override
HsBookingProjectRepository repo(final HsBookingProjectRepositoryIntegrationTest test) {
return test.realProjectRepo;
}
@Override
void assertResult(
final HsBookingProjectRepositoryIntegrationTest test,
final List<? extends HsBookingProject> result,
final String... expectedProjects) {
test.allTheseBookingProjectsAreReturned(result, expectedProjects);
}
},
RBAC {
@Override
HsBookingProjectRepository repo(final HsBookingProjectRepositoryIntegrationTest test) {
return test.rbacProjectRepo;
}
@Override
void assertResult(
final HsBookingProjectRepositoryIntegrationTest test,
final List<? extends HsBookingProject> result,
final String... expectedProjects) {
test.exactlyTheseBookingProjectsAreReturned(result, expectedProjects);
}
};
abstract HsBookingProjectRepository repo(final HsBookingProjectRepositoryIntegrationTest test);
abstract void assertResult(final HsBookingProjectRepositoryIntegrationTest test, final List<? extends HsBookingProject> result, final String... expectedProjects);
}
}

View File

@ -7,8 +7,7 @@ import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.
@UtilityClass
public class TestHsBookingProject {
public static final HsBookingProjectEntity TEST_PROJECT = HsBookingProjectEntity.builder()
public static final HsBookingProjectRealEntity PROJECT_TEST_ENTITY = HsBookingProjectRealEntity.builder()
.debitor(TEST_BOOKING_DEBITOR)
.caption("test project")
.build();

View File

@ -0,0 +1,27 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
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.lenient;
import static org.mockito.Mockito.mock;
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);
lenient().when(em.createQuery(any(), any(Class.class))).thenReturn(assetQuery);
lenient().when(assetQuery.getResultStream()).thenReturn(assetStream);
lenient().when(assetQuery.setParameter(anyString(), any())).thenReturn(assetQuery);
lenient().when(assetStream.findFirst()).thenReturn(Optional.ofNullable(asset));
return em;
}
}

View File

@ -4,13 +4,13 @@ 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.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.ClassOrderer;
@ -50,19 +50,16 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
private Integer port;
@Autowired
HsHostingAssetRepository assetRepo;
HsHostingAssetRealRepository realAssetRepo;
@Autowired
HsBookingItemRepository bookingItemRepo;
HsBookingItemRealRepository realBookingItemRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingProjectRealRepository realProjectRepo;
@Autowired
HsOfficeDebitorRepository debitorRepo;
@Autowired
HsOfficeContactRbacRepository contactRepo;
HsOfficeContactRealRepository realContactRepo;
@Autowired
JpaAttempt jpaAttempt;
@ -76,7 +73,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
// given
context("superuser-alex@hostsharing.net");
final var givenProject = projectRepo.findByCaption("D-1000111 default project").stream()
final var givenProject = realProjectRepo.findByCaption("D-1000111 default project").stream()
.findAny().orElseThrow();
RestAssured // @formatter:off
@ -189,13 +186,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
final var newWebspace = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1));
assertThat(newWebspace).isNotNull();
toCleanup(HsHostingAssetEntity.class, newWebspace);
toCleanup(HsHostingAssetRbacEntity.class, newWebspace);
}
@Test
void parentAssetAgent_canAddSubAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenParentAsset = givenParentAsset(MANAGED_WEBSPACE, "fir01");
final var location = RestAssured // @formatter:off
@ -273,7 +269,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
final var newWebspace = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1));
assertThat(newWebspace).isNotNull();
toCleanup(HsHostingAssetEntity.class, newWebspace);
toCleanup(HsHostingAssetRbacEntity.class, newWebspace);
}
@Test
@ -320,18 +316,18 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void totalsLimitValidationsArePerformend_whenAddingAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenHostingAsset = givenHostingAsset(MANAGED_WEBSPACE, "fir01");
final var givenHostingAsset = givenRealHostingAsset(MANAGED_WEBSPACE, "fir01");
assertThat(givenHostingAsset.getBookingItem().getResources().get("Multi"))
.as("precondition failed")
.isEqualTo(1);
final var preExistingUnixUserCount = assetRepo.findAllByCriteria(null, givenHostingAsset.getUuid(), UNIX_USER).size();
final var preExistingUnixUserCount = realAssetRepo.findAllByCriteria(null, givenHostingAsset.getUuid(), UNIX_USER).size();
final var UNIX_USER_PER_MULTI_OPTION = 25;
jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION -preExistingUnixUserCount+1; ++n) {
toCleanup(assetRepo.save(
HsHostingAssetEntity.builder()
toCleanup(realAssetRepo.save(
HsHostingAssetRealEntity.builder()
.type(UNIX_USER)
.parentAsset(givenHostingAsset)
.identifier("fir01-%2d".formatted(n))
@ -375,7 +371,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Test
void globalAdmin_canGetArbitraryAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenAssetUuid = assetRepo.findByIdentifier("vm1011").stream()
final var givenAssetUuid = realAssetRepo.findByIdentifier("vm1011").stream()
.filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000111 default project"))
.findAny().orElseThrow().getUuid();
@ -399,9 +395,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Test
void normalUser_canNotGetUnrelatedAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenAssetUuid = assetRepo.findByIdentifier("vm1012").stream()
final var givenAssetUuid = realAssetRepo.findByIdentifier("vm1012").stream()
.filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000212 default project"))
.map(HsHostingAssetEntity::getUuid)
.map(HsHostingAssetRealEntity::getUuid)
.findAny().orElseThrow();
RestAssured // @formatter:off
@ -417,7 +413,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Test
void projectAgentUser_canGetRelatedAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenAssetUuid = assetRepo.findByIdentifier("vm1013").stream()
final var givenAssetUuid = realAssetRepo.findByIdentifier("vm1013").stream()
.filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000313 default project"))
.findAny().orElseThrow().getUuid();
@ -449,7 +445,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void globalAdmin_canPatchAllUpdatablePropertiesOfAsset() {
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder()
HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID())
.bookingItem(givenSomeNewBookingItem(
"D-1000111 default project",
@ -510,8 +506,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
// finally, the asset is actually updated
em.clear();
context.define("superuser-alex@hostsharing.net");
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
assertThat(realAssetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
.matches(asset -> {
assertThat(asset.getAlarmContact()).isNotNull()
.extracting(c -> c.getEmailAddresses().get("main"))
@ -533,10 +528,10 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void assetAdmin_canPatchAllUpdatablePropertiesOfAsset() {
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder()
HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID())
.type(UNIX_USER)
.parentAsset(givenHostingAsset(MANAGED_WEBSPACE, "fir01"))
.parentAsset(givenRealHostingAsset(MANAGED_WEBSPACE, "fir01"))
.identifier("fir01-temp")
.caption("some test-unix-user")
.build());
@ -586,8 +581,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
// finally, the asset is actually updated
assertThat(jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
return assetRepo.findByUuid(givenAsset.getUuid());
return realAssetRepo.findByUuid(givenAsset.getUuid());
}).returnedValue()).isPresent().get()
.matches(asset -> {
assertThat(asset.getCaption()).isEqualTo("some patched test-unix-user");
@ -611,7 +605,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void globalAdmin_canDeleteArbitraryAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder()
HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID())
.bookingItem(givenSomeNewBookingItem(
"D-1000111 default project",
@ -637,14 +631,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(204); // @formatter:on
// then the given assets is gone
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isEmpty();
assertThat(realAssetRepo.findByUuid(givenAsset.getUuid())).isEmpty();
}
@Test
void normalUser_canNotDeleteUnrelatedAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder()
HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID())
.bookingItem(givenSomeNewBookingItem(
"D-1000111 default project",
@ -670,40 +664,40 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(404); // @formatter:on
// then the given asset is still there
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isNotEmpty();
assertThat(realAssetRepo.findByUuid(givenAsset.getUuid())).isNotEmpty();
}
}
HsHostingAssetEntity givenHostingAsset(final HsHostingAssetType type, final String identifier) {
return assetRepo.findByIdentifier(identifier).stream()
HsHostingAssetRealEntity givenRealHostingAsset(final HsHostingAssetType type, final String identifier) {
return realAssetRepo.findByIdentifier(identifier).stream()
.filter(ha -> ha.getType() == type)
.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 = projectRepo.findByCaption(projectCaption).stream()
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) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
final var project = projectRepo.findByCaption(projectCaption).getFirst();
final var project = realProjectRepo.findByCaption(projectCaption).getFirst();
final var resources = switch (bookingItemType) {
case MANAGED_SERVER -> Map.<String, Object>ofEntries(entry("CPU", 1),
entry("RAM", 20),
@ -711,34 +705,34 @@ 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();
}
HsHostingAssetEntity givenParentAsset(final HsHostingAssetType assetType, final String assetIdentifier) {
final var givenAsset = assetRepo.findByIdentifier(assetIdentifier).stream()
HsHostingAssetRealEntity givenParentAsset(final HsHostingAssetType assetType, final String assetIdentifier) {
final var givenAsset = realAssetRepo.findByIdentifier(assetIdentifier).stream()
.filter(a -> a.getType() == assetType)
.findAny().orElseThrow();
return givenAsset;
}
private HsHostingAssetEntity givenSomeTemporaryHostingAsset(final Supplier<HsHostingAssetEntity> newAsset) {
private HsHostingAssetRealEntity givenSomeTemporaryHostingAsset(final Supplier<HsHostingAssetRealEntity> newAsset) {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
return toCleanup(assetRepo.save(newAsset.get()));
context.define("superuser-alex@hostsharing.net"); // needed to determine creator
return toCleanup(realAssetRepo.save(newAsset.get()));
}).assertSuccessful().returnedValue();
}
private HsOfficeContactRbacEntity givenContact() {
private HsOfficeContactRealEntity givenContact() {
return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
return contactRepo.findContactByOptionalCaptionLike("second").stream().findFirst().orElseThrow();
context.define("superuser-alex@hostsharing.net"); // needed to determine creator
return realContactRepo.findContactByOptionalCaptionLike("second").stream().findFirst().orElseThrow();
}).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,10 +28,10 @@ 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.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
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;
import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
import static org.assertj.core.api.Assertions.assertThat;
@ -62,17 +62,20 @@ public class HsHostingAssetControllerRestTest {
@MockBean
@SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController
private HsBookingItemRepository bookingItemRepo;
private HsBookingItemRealRepository realBookingItemRepo;
@MockBean
private HsHostingAssetRepository hostingAssetRepo;
private HsHostingAssetRealRepository realAssetRepo;
@MockBean
private HsHostingAssetRbacRepository rbacAssetRepo;
enum ListTestCases {
CLOUD_SERVER(
List.of(
HsHostingAssetEntity.builder()
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)
@ -96,9 +99,9 @@ public class HsHostingAssetControllerRestTest {
"""),
MANAGED_SERVER(
List.of(
HsHostingAssetEntity.builder()
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)
@ -131,9 +134,9 @@ public class HsHostingAssetControllerRestTest {
"""),
UNIX_USER(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.UNIX_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("xyz00-office")
.caption("some fake Unix-User")
.config(Map.ofEntries(
@ -165,9 +168,9 @@ public class HsHostingAssetControllerRestTest {
"""),
EMAIL_ALIAS(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.EMAIL_ALIAS)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("xyz00-office")
.caption("some fake EMail-Alias")
.config(Map.ofEntries(
@ -189,7 +192,7 @@ public class HsHostingAssetControllerRestTest {
"""),
DOMAIN_SETUP(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_SETUP)
.identifier("example.org")
.caption("some fake Domain-Setup")
@ -207,7 +210,7 @@ public class HsHostingAssetControllerRestTest {
"""),
DOMAIN_DNS_SETUP(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_DNS_SETUP)
.identifier("example.org")
.caption("some fake Domain-DNS-Setup")
@ -250,7 +253,7 @@ public class HsHostingAssetControllerRestTest {
"""),
DOMAIN_HTTP_SETUP(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_HTTP_SETUP)
.identifier("example.org|HTTP")
.caption("some fake Domain-HTTP-Setup")
@ -303,7 +306,7 @@ public class HsHostingAssetControllerRestTest {
"""),
DOMAIN_SMTP_SETUP(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_SMTP_SETUP)
.identifier("example.org|SMTP")
.caption("some fake Domain-SMTP-Setup")
@ -321,7 +324,7 @@ public class HsHostingAssetControllerRestTest {
"""),
DOMAIN_MBOX_SETUP(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_MBOX_SETUP)
.identifier("example.org|MBOX")
.caption("some fake Domain-MBOX-Setup")
@ -339,9 +342,9 @@ public class HsHostingAssetControllerRestTest {
"""),
EMAIL_ADDRESS(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.EMAIL_ADDRESS)
.parentAsset(HsHostingAssetEntity.builder()
.parentAsset(HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.DOMAIN_MBOX_SETUP)
.identifier("example.org|MBOX")
.caption("some fake Domain-MBOX-Setup")
@ -367,9 +370,9 @@ public class HsHostingAssetControllerRestTest {
"""),
MARIADB_INSTANCE(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MARIADB_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|MariaDB.default")
.caption("some fake MariaDB instance")
.build()),
@ -386,7 +389,7 @@ public class HsHostingAssetControllerRestTest {
"""),
MARIADB_USER(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MARIADB_USER)
.identifier("xyz00_temp")
.caption("some fake MariaDB user")
@ -404,7 +407,7 @@ public class HsHostingAssetControllerRestTest {
"""),
MARIADB_DATABASE(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MARIADB_DATABASE)
.identifier("xyz00_temp")
.caption("some fake MariaDB database")
@ -429,9 +432,9 @@ public class HsHostingAssetControllerRestTest {
"""),
PGSQL_INSTANCE(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.PGSQL_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|PgSql.default")
.caption("some fake PgSql instance")
.build()),
@ -448,7 +451,7 @@ public class HsHostingAssetControllerRestTest {
"""),
PGSQL_USER(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.PGSQL_USER)
.identifier("xyz00_temp")
.caption("some fake PgSql user")
@ -466,7 +469,7 @@ public class HsHostingAssetControllerRestTest {
"""),
PGSQL_DATABASE(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.PGSQL_DATABASE)
.identifier("xyz00_temp")
.caption("some fake PgSql database")
@ -491,9 +494,9 @@ public class HsHostingAssetControllerRestTest {
"""),
IPV4_NUMBER(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.IPV4_NUMBER)
.assignedToAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.assignedToAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("11.12.13.14")
.caption("some fake IPv4 number")
.build()),
@ -510,9 +513,9 @@ public class HsHostingAssetControllerRestTest {
"""),
IPV6_NUMBER(
List.of(
HsHostingAssetEntity.builder()
HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.IPV6_NUMBER)
.assignedToAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.assignedToAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("2001:db8:3333:4444:5555:6666:7777:8888")
.caption("some fake IPv6 number")
.build()),
@ -529,13 +532,13 @@ public class HsHostingAssetControllerRestTest {
""");
final HsHostingAssetType assetType;
final List<HsHostingAssetEntity> givenHostingAssetsOfType;
final List<HsHostingAssetRbacEntity> givenHostingAssetsOfType;
final String expectedResponse;
final JsonNode expectedResponseJson;
@SneakyThrows
ListTestCases(
final List<HsHostingAssetEntity> givenHostingAssetsOfType,
final List<HsHostingAssetRbacEntity> givenHostingAssetsOfType,
final String expectedResponse) {
this.assetType = HsHostingAssetType.valueOf(name());
this.givenHostingAssetsOfType = givenHostingAssetsOfType;
@ -561,7 +564,7 @@ public class HsHostingAssetControllerRestTest {
@EnumSource(HsHostingAssetControllerRestTest.ListTestCases.class)
void shouldListAssets(final HsHostingAssetControllerRestTest.ListTestCases testCase) throws Exception {
// given
when(hostingAssetRepo.findAllByCriteria(null, null, testCase.assetType))
when(rbacAssetRepo.findAllByCriteria(null, null, testCase.assetType))
.thenReturn(testCase.givenHostingAssetsOfType);
// when

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;
@ -27,7 +27,7 @@ import static org.mockito.Mockito.lenient;
@ExtendWith(MockitoExtension.class)
class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
HsHostingAssetPatchResource,
HsHostingAssetEntity
HsHostingAssetRbacEntity
> {
private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID();
@ -60,17 +60,17 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
@BeforeEach
void initMocks() {
lenient().when(em.getReference(eq(HsHostingAssetEntity.class), any())).thenAnswer(invocation ->
HsHostingAssetEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsHostingAssetRbacEntity.class), any())).thenAnswer(invocation ->
HsHostingAssetRbacEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsOfficeContactRealEntity.class), any())).thenAnswer(invocation ->
HsOfficeContactRealEntity.builder().uuid(invocation.getArgument(1)).build());
}
@Override
protected HsHostingAssetEntity newInitialEntity() {
final var entity = new HsHostingAssetEntity();
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);
@ -83,7 +83,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
}
@Override
protected HsHostingAssetEntityPatcher createPatcher(final HsHostingAssetEntity server) {
protected HsHostingAssetEntityPatcher createPatcher(final HsHostingAssetRbacEntity server) {
return new HsHostingAssetEntityPatcher(em, server);
}
@ -94,19 +94,19 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
"caption",
HsHostingAssetPatchResource::setCaption,
PATCHED_CAPTION,
HsHostingAssetEntity::setCaption),
HsHostingAssetRbacEntity::setCaption),
new SimpleProperty<>(
"config",
HsHostingAssetPatchResource::setConfig,
PATCH_CONFIG,
HsHostingAssetEntity::putConfig,
HsHostingAssetRbacEntity::putConfig,
PATCHED_CONFIG)
.notNullable(),
new JsonNullableProperty<>(
"alarmContact",
HsHostingAssetPatchResource::setAlarmContactUuid,
PATCHED_CONTACT_UUID,
HsHostingAssetEntity::setAlarmContact,
HsHostingAssetRbacEntity::setAlarmContact,
newContact(PATCHED_CONTACT_UUID))
);
}

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 HsHostingAssetEntity givenParentAsset = HsHostingAssetEntity.builder()
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
final HsHostingAssetRealEntity givenParentAsset = HsHostingAssetRealEntity.builder()
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234")
.caption("some managed asset")
@ -20,8 +20,8 @@ class HsHostingAssetEntityUnitTest {
entry("SSD-storage", 512),
entry("HDD-storage", 2048)))
.build();
final HsHostingAssetEntity givenWebspace = HsHostingAssetEntity.builder()
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
final HsHostingAssetRealEntity givenWebspace = HsHostingAssetRealEntity.builder()
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.parentAsset(givenParentAsset)
.identifier("xyz00")
@ -31,7 +31,7 @@ class HsHostingAssetEntityUnitTest {
entry("SSD-storage", 512),
entry("HDD-storage", 2048)))
.build();
final HsHostingAssetEntity givenUnixUser = HsHostingAssetEntity.builder()
final HsHostingAssetRealEntity givenUnixUser = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.UNIX_USER)
.parentAsset(givenWebspace)
.identifier("xyz00-web")
@ -42,7 +42,7 @@ class HsHostingAssetEntityUnitTest {
entry("HDD-soft-quota", 256),
entry("HDD-hard-quota", 512)))
.build();
final HsHostingAssetEntity givenDomainHttpSetup = HsHostingAssetEntity.builder()
final HsHostingAssetRealEntity givenDomainHttpSetup = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.DOMAIN_HTTP_SETUP)
.parentAsset(givenWebspace)
.identifier("example.org")
@ -58,13 +58,13 @@ class HsHostingAssetEntityUnitTest {
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
assertThat(givenWebspace.toString()).isEqualToIgnoringWhitespace(
"HsHostingAssetEntity(MANAGED_WEBSPACE, xyz00, some managed webspace, MANAGED_SERVER:vm1234, D-1234500:test project:test cloud server booking item, { \"CPU\": 2, \"HDD-storage\": 2048, \"SSD-storage\": 512 })");
"HsHostingAsset(MANAGED_WEBSPACE, xyz00, some managed webspace, MANAGED_SERVER:vm1234, D-1234500:test project:test cloud server booking item, { \"CPU\": 2, \"HDD-storage\": 2048, \"SSD-storage\": 512 })");
assertThat(givenUnixUser.toString()).isEqualToIgnoringWhitespace(
"HsHostingAssetEntity(UNIX_USER, xyz00-web, some unix-user, MANAGED_WEBSPACE:xyz00, { \"HDD-hard-quota\": 512, \"HDD-soft-quota\": 256, \"SSD-hard-quota\": 256, \"SSD-soft-quota\": 128 })");
"HsHostingAsset(UNIX_USER, xyz00-web, some unix-user, MANAGED_WEBSPACE:xyz00, { \"HDD-hard-quota\": 512, \"HDD-soft-quota\": 256, \"SSD-hard-quota\": 256, \"SSD-soft-quota\": 128 })");
assertThat(givenDomainHttpSetup.toString()).isEqualToIgnoringWhitespace(
"HsHostingAssetEntity(DOMAIN_HTTP_SETUP, example.org, some domain setup, MANAGED_WEBSPACE:xyz00, UNIX_USER:xyz00-web, { \"option-htdocsfallback\": true, \"use-fcgiphpbin\": \"/usr/lib/cgi-bin/php\", \"validsubdomainnames\": \"*\" })");
"HsHostingAsset(DOMAIN_HTTP_SETUP, example.org, some domain setup, MANAGED_WEBSPACE:xyz00, UNIX_USER:xyz00-web, { \"option-htdocsfallback\": true, \"use-fcgiphpbin\": \"/usr/lib/cgi-bin/php\", \"validsubdomainnames\": \"*\" })");
}
@Test

View File

@ -1,10 +1,10 @@
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.HsBookingProjectRepository;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRbacRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.hsadminng.mapper.Array;
@ -12,6 +12,8 @@ import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean;
@ -42,13 +44,16 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired
HsHostingAssetRepository assetRepo;
HsHostingAssetRealRepository realAssetRepo;
@Autowired
HsBookingItemRepository bookingItemRepo;
HsHostingAssetRbacRepository rbacAssetRepo;
@Autowired
HsBookingProjectRepository projectRepo;
HsBookingItemRealRepository realBookingItemRepo;
@Autowired
HsBookingProjectRbacRepository projectRepo;
@Autowired
RawRbacRoleRepository rawRoleRepo;
@ -71,34 +76,35 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
@Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewAsset() {
// given
context("superuser-alex@hostsharing.net");
final var count = assetRepo.count();
context("superuser-alex@hostsharing.net"); // TODO.test: remove context(...) once all entities have real entities
final var count = realAssetRepo.count();
final var givenManagedServer = givenHostingAsset("D-1000111 default project", MANAGED_SERVER);
final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01");
// when
final var result = attempt(em, () -> {
final var newAsset = HsHostingAssetEntity.builder()
final var newAsset = HsHostingAssetRbacEntity.builder()
.bookingItem(newWebspaceBookingItem)
.parentAsset(givenManagedServer)
.caption("some new managed webspace")
.type(MANAGED_WEBSPACE)
.identifier("xyz90")
.build();
return toCleanup(assetRepo.save(newAsset));
return toCleanup(rbacAssetRepo.save(newAsset));
});
// then
result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetEntity::getUuid).isNotNull();
assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetRbacEntity::getUuid).isNotNull();
assertThatAssetIsPersisted(result.returnedValue());
assertThat(result.returnedValue().isLoaded()).isFalse();
assertThat(assetRepo.count()).isEqualTo(count + 1);
assertThat(realAssetRepo.count()).isEqualTo(count + 1);
}
@Test
public void createsAndGrantsRoles() {
// given
// TODO.test: remove context(...) once all entities have real entities
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
final var givenManagedServer = givenHostingAsset("D-1000111 default project", MANAGED_SERVER);
final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01");
@ -107,15 +113,16 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
// when
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
final var result = attempt(em, () -> {
final var newAsset = HsHostingAssetEntity.builder()
final var newAsset = HsHostingAssetRbacEntity.builder()
.bookingItem(newWebspaceBookingItem)
.parentAsset(givenManagedServer)
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("fir00")
.caption("some new managed webspace")
.build();
return toCleanup(assetRepo.save(newAsset));
return toCleanup(rbacAssetRepo.save(newAsset));
});
// then
@ -163,18 +170,18 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when
context("person-SmithPeter@example.com");
final var result = attempt(em, () -> {
final var newAsset = HsHostingAssetEntity.builder()
final var newAsset = HsHostingAssetRbacEntity.builder()
.type(DOMAIN_SETUP)
.identifier("example.net")
.caption("some new domain setup")
.build();
return assetRepo.save(newAsset);
return rbacAssetRepo.save(newAsset);
});
// then
// ... the domain setup was created and returned
result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetEntity::getUuid).isNotNull();
assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetRbacEntity::getUuid).isNotNull();
assertThat(result.returnedValue().isLoaded()).isFalse();
// ... the creating user can read the new domain setup
@ -186,11 +193,11 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
assertThatAssetIsPersisted(result.returnedValue());
}
private void assertThatAssetIsPersisted(final HsHostingAssetEntity saved) {
private void assertThatAssetIsPersisted(final HsHostingAssetRbacEntity saved) {
em.clear();
attempt(em, () -> {
final var found = assetRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsHostingAssetEntity::toString).contains(saved.toString());
final var found = realAssetRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsHostingAsset::toString).contains(saved.toString());
});
}
}
@ -198,20 +205,21 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
@Nested
class FindAssets {
@Test
public void globalAdmin_withoutAssumedRole_canViewArbitraryAssetsOfAllDebitors() {
@ParameterizedTest
@EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canViewArbitraryAssetsOfAllDebitors(final TestCase testCase) {
// given
context("superuser-alex@hostsharing.net");
// when
final var result = assetRepo.findAllByCriteria(null, null, MANAGED_WEBSPACE);
final var result = repoUnderTest(testCase).findAllByCriteria(null, null, MANAGED_WEBSPACE);
// then
exactlyTheseAssetsAreReturned(
result,
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)",
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedWebspace)",
"HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedWebspace)");
"HsHostingAsset(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)",
"HsHostingAsset(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedWebspace)",
"HsHostingAsset(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedWebspace)");
}
@Test
@ -222,33 +230,32 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
.findAny().orElseThrow().getUuid();
// when:
final var result = assetRepo.findAllByCriteria(projectUuid, null, null);
final var result = rbacAssetRepo.findAllByCriteria(projectUuid, null, null);
// then:
exactlyTheseAssetsAreReturned(
result,
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedWebspace)",
"HsHostingAssetEntity(MANAGED_SERVER, vm1011, some ManagedServer, D-1000111:D-1000111 default project:separate ManagedServer, { monit_max_cpu_usage : 90, monit_max_ram_usage : 80, monit_max_ssd_usage : 70 })");
"HsHostingAsset(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedWebspace)",
"HsHostingAsset(MANAGED_SERVER, vm1011, some ManagedServer, D-1000111:D-1000111 default project:separate ManagedServer, { monit_max_cpu_usage : 90, monit_max_ram_usage : 80, monit_max_ssd_usage : 70 })");
}
@Test
public void managedServerAgent_canFindAssetsRelatedToManagedServer() {
// given
context("superuser-alex@hostsharing.net");
final var parentAssetUuid = assetRepo.findByIdentifier("vm1012").stream()
final var parentAssetUuid = realAssetRepo.findByIdentifier("vm1012").stream()
.filter(ha -> ha.getType() == MANAGED_SERVER)
.findAny().orElseThrow().getUuid();
// when
context("superuser-alex@hostsharing.net", "hs_hosting_asset#vm1012:AGENT");
final var result = assetRepo.findAllByCriteria(null, parentAssetUuid, null);
final var result = rbacAssetRepo.findAllByCriteria(null, parentAssetUuid, null);
// then
exactlyTheseAssetsAreReturned(
result,
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)",
"HsHostingAssetEntity(MARIADB_INSTANCE, vm1012.MariaDB.default, some default MariaDB instance, MANAGED_SERVER:vm1012)",
"HsHostingAssetEntity(PGSQL_INSTANCE, vm1012.Postgresql.default, some default Postgresql instance, MANAGED_SERVER:vm1012)");
"HsHostingAsset(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)",
"HsHostingAsset(MARIADB_INSTANCE, vm1012.MariaDB.default, some default MariaDB instance, MANAGED_SERVER:vm1012)",
"HsHostingAsset(PGSQL_INSTANCE, vm1012.Postgresql.default, some default Postgresql instance, MANAGED_SERVER:vm1012)");
}
@Test
@ -258,12 +265,12 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when
context("superuser-alex@hostsharing.net", "hs_hosting_asset#sec01:AGENT");
final var result = assetRepo.findAllByCriteria(null, null, EMAIL_ADDRESS);
final var result = rbacAssetRepo.findAllByCriteria(null, null, EMAIL_ADDRESS);
// then
exactlyTheseAssetsAreReturned(
result,
"HsHostingAssetEntity(EMAIL_ADDRESS, test@sec.example.org, some E-Mail-Address, DOMAIN_MBOX_SETUP:sec.example.org|MBOX)");
"HsHostingAsset(EMAIL_ADDRESS, test@sec.example.org, some E-Mail-Address, DOMAIN_MBOX_SETUP:sec.example.org|MBOX)");
}
}
@ -278,25 +285,24 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
final var foundAsset = em.find(HsHostingAssetEntity.class, givenAssetUuid);
final var foundAsset = em.find(HsHostingAssetRbacEntity.class, givenAssetUuid);
foundAsset.getConfig().put("CPU", 2);
foundAsset.getConfig().remove("SSD-storage");
foundAsset.getConfig().put("HSD-storage", 2048);
return toCleanup(assetRepo.save(foundAsset));
return toCleanup(rbacAssetRepo.save(foundAsset));
});
// then
result.assertSuccessful();
jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
assertThatAssetActuallyInDatabase(result.returnedValue());
}).assertSuccessful();
}
private void assertThatAssetActuallyInDatabase(final HsHostingAssetEntity saved) {
final var found = assetRepo.findByUuid(saved.getUuid());
private void assertThatAssetActuallyInDatabase(final HsHostingAssetRbacEntity saved) {
final var found = realAssetRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved)
.extracting(HsHostingAssetEntity::getVersion).isEqualTo(saved.getVersion());
.extracting(HsHostingAsset::getVersion).isEqualTo(saved.getVersion());
}
}
@ -312,51 +318,47 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
assetRepo.deleteByUuid(givenAsset.getUuid());
rbacAssetRepo.deleteByUuid(givenAsset.getUuid());
});
// then
result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null);
return assetRepo.findByUuid(givenAsset.getUuid());
return realAssetRepo.findByUuid(givenAsset.getUuid());
}).assertSuccessful().returnedValue()).isEmpty();
}
@Test
public void relatedOwner_canDeleteTheirRelatedAsset() {
// given
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000");
// when
final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent();
assertThat(rbacAssetRepo.findByUuid(givenAsset.getUuid())).isPresent();
assetRepo.deleteByUuid(givenAsset.getUuid());
rbacAssetRepo.deleteByUuid(givenAsset.getUuid());
});
// then
result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null);
return assetRepo.findByUuid(givenAsset.getUuid());
return realAssetRepo.findByUuid(givenAsset.getUuid());
}).assertSuccessful().returnedValue()).isEmpty();
}
@Test
public void relatedAdmin_canNotDeleteTheirRelatedAsset() {
// given
context("superuser-alex@hostsharing.net", null);
final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000");
// when
final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_hosting_asset#vm1000:ADMIN");
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent();
assertThat(rbacAssetRepo.findByUuid(givenAsset.getUuid())).isPresent();
assetRepo.deleteByUuid(givenAsset.getUuid());
rbacAssetRepo.deleteByUuid(givenAsset.getUuid());
});
// then
@ -364,15 +366,13 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
JpaSystemException.class,
"[403] Subject ", " is not allowed to delete hs_hosting_asset");
assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return assetRepo.findByUuid(givenAsset.getUuid());
return realAssetRepo.findByUuid(givenAsset.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there
}
@Test
public void deletingAnAssetAlsoDeletesRelatedRolesAndGrants() {
// given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll()));
final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000");
@ -380,7 +380,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when
final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
return assetRepo.deleteByUuid(givenAsset.getUuid());
return rbacAssetRepo.deleteByUuid(givenAsset.getUuid());
});
// then
@ -410,57 +410,89 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
"[creating hosting-asset test-data D-1000313 default project, hs_hosting_asset, INSERT]");
}
private HsHostingAssetEntity givenSomeTemporaryAsset(final String projectCaption, final String identifier) {
private HsHostingAssetRealEntity givenSomeTemporaryAsset(final String projectCaption, final String identifier) {
return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
context("superuser-alex@hostsharing.net"); // needed to determine creator
final var givenBookingItem = givenBookingItem("D-1000111 default project", "test CloudServer");
final var newAsset = HsHostingAssetEntity.builder()
final var newAsset = HsHostingAssetRealEntity.builder()
.bookingItem(givenBookingItem)
.type(CLOUD_SERVER)
.identifier(identifier)
.caption("some temp cloud asset")
.caption(projectCaption)
.config(Map.ofEntries(
entry("CPU", 1),
entry("SSD-storage", 256)))
.build();
return toCleanup(assetRepo.save(newAsset));
return toCleanup(realAssetRepo.save(newAsset));
}).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();
}
HsHostingAssetEntity givenHostingAsset(final String projectCaption, final HsHostingAssetType type) {
HsHostingAssetRealEntity givenHostingAsset(final String projectCaption, final HsHostingAssetType type) {
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow();
return assetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream()
return realAssetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream()
.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(
final List<HsHostingAssetEntity> actualResult,
final List<? extends HsHostingAsset> actualResult,
final String... serverNames) {
assertThat(actualResult)
.extracting(HsHostingAssetEntity::toString)
.extracting(HsHostingAsset::toString)
.extracting(input -> input.replaceAll("\\s+", " "))
.extracting(input -> input.replaceAll("\"", ""))
.extracting(input -> input.replaceAll("\" : ", "\": "))
.containsExactlyInAnyOrder(serverNames);
}
void allTheseBookingProjectsAreReturned(
final List<? extends HsHostingAsset> actualResult,
final String... serverNames) {
assertThat(actualResult)
.extracting(HsHostingAsset::toString)
.extracting(input -> input.replaceAll("\\s+", " "))
.extracting(input -> input.replaceAll("\"", ""))
.extracting(input -> input.replaceAll("\" : ", "\": "))
.contains(serverNames);
}
private HsHostingAssetRepository<? extends HsHostingAsset> repoUnderTest(final HsHostingAssetRepositoryIntegrationTest.TestCase testCase) {
return testCase.repo(HsHostingAssetRepositoryIntegrationTest.this);
}
enum TestCase {
REAL {
@Override
HsHostingAssetRepository<HsHostingAssetRealEntity> repo(final HsHostingAssetRepositoryIntegrationTest test) {
return test.realAssetRepo;
}
},
RBAC {
@Override
HsHostingAssetRepository<HsHostingAssetRbacEntity> repo(final HsHostingAssetRepositoryIntegrationTest test) {
return test.rbacAssetRepo;
}
};
abstract HsHostingAssetRepository<? extends HsHostingAsset> repo(final HsHostingAssetRepositoryIntegrationTest test);
}
}

View File

@ -0,0 +1,36 @@
package net.hostsharing.hsadminng.hs.hosting.asset;
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 {
public static final HsHostingAssetRbacEntity MANAGED_SERVER_HOSTING_ASSET_RBAC_TEST_ENTITY = HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234")
.caption("some managed server")
.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(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(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(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.build();
}

View File

@ -1,22 +0,0 @@
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;
public class TestHsHostingAssetEntities {
public static final HsHostingAssetEntity TEST_MANAGED_SERVER_HOSTING_ASSET = HsHostingAssetEntity.builder()
.type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234")
.caption("some managed server")
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.build();
public static final HsHostingAssetEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET = HsHostingAssetEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("xyz00")
.caption("some managed webspace")
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM)
.build();
}

View File

@ -1,14 +1,15 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
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;
@ -18,7 +19,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test
void validatesProperties() {
// given
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder()
final var cloudServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(CLOUD_SERVER)
.identifier("vm1234")
.config(Map.ofEntries(
@ -40,10 +41,10 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test
void validatesInvalidIdentifier() {
// given
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder()
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());
@ -68,10 +69,10 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test
void validatesBookingItemType() {
// given
final var mangedServerHostingAssetEntity = HsHostingAssetEntity.builder()
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());
@ -86,12 +87,12 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = HsHostingAssetEntity.builder()
final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(CLOUD_SERVER)
.identifier("vm1234")
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_SERVER).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(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();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,20 +1,21 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
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;
import static java.util.Map.entry;
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.DOMAIN_DNS_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_COMMENT;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_RECORD_DATA;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_RECORD_TYPE;
@ -25,16 +26,18 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsDomainDnsSetupHostingAssetValidatorUnitTest {
static final HsHostingAssetEntity validDomainSetupEntity = HsHostingAssetEntity.builder()
static final HsHostingAssetRealEntity validDomainSetupEntity = HsHostingAssetRealEntity.builder()
.type(DOMAIN_SETUP)
.identifier("example.org")
.build();
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
private EntityManager em;
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(DOMAIN_DNS_SETUP)
.parentAsset(validDomainSetupEntity)
.assignedToAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.assignedToAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("example.org|DNS")
.config(Map.ofEntries(
entry("TTL", 21600),
@ -139,9 +142,9 @@ 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(HsHostingAssetEntity.builder().type(DOMAIN_SETUP).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(DOMAIN_SETUP).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,9 +1,9 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.mapper.Array;
import org.junit.jupiter.api.Test;
@ -18,16 +18,16 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsDomainHttpSetupHostingAssetValidatorUnitTest {
static final HsHostingAssetEntity validDomainSetupEntity = HsHostingAssetEntity.builder()
static final HsHostingAssetRealEntity validDomainSetupEntity = HsHostingAssetRealEntity.builder()
.type(DOMAIN_SETUP)
.identifier("example.org")
.build();
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(DOMAIN_HTTP_SETUP)
.parentAsset(validDomainSetupEntity)
.assignedToAsset(HsHostingAssetEntity.builder().type(UNIX_USER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(UNIX_USER).build())
.identifier("example.org|HTTP")
.config(Map.ofEntries(
entry("passenger-errorpage", true),
@ -109,8 +109,8 @@ class HsDomainHttpSetupHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(null)
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,9 +1,9 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.junit.jupiter.api.Test;
import java.util.Map;
@ -16,16 +16,16 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsDomainMboxHostingAssetValidatorUnitTest {
static final HsHostingAssetEntity validDomainSetupEntity = HsHostingAssetEntity.builder()
static final HsHostingAssetRealEntity validDomainSetupEntity = HsHostingAssetRealEntity.builder()
.type(DOMAIN_SETUP)
.identifier("example.org")
.build();
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(DOMAIN_MBOX_SETUP)
.parentAsset(validDomainSetupEntity)
.assignedToAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.identifier("example.org|MBOX");
}
@ -84,8 +84,8 @@ class HsDomainMboxHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(null)
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,9 +1,9 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
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.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
@ -17,8 +17,8 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsDomainSetupHostingAssetValidatorUnitTest {
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(DOMAIN_SETUP)
.identifier("example.org");
}
@ -94,9 +94,9 @@ class HsDomainSetupHostingAssetValidatorUnitTest {
void validatesReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.parentAsset(HsHostingAssetEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(MANAGED_SERVER).build())
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,9 +1,10 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.junit.jupiter.api.Test;
import java.util.Map;
@ -16,16 +17,16 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsDomainSmtpSetupHostingAssetValidatorUnitTest {
static final HsHostingAssetEntity validDomainSetupEntity = HsHostingAssetEntity.builder()
static final HsHostingAssetRealEntity validDomainSetupEntity = HsHostingAssetRealEntity.builder()
.type(DOMAIN_SETUP)
.identifier("example.org")
.build();
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(DOMAIN_SMTP_SETUP)
.parentAsset(validDomainSetupEntity)
.assignedToAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.identifier("example.org|SMTP");
}
@ -84,8 +85,8 @@ class HsDomainSmtpSetupHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(null)
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,6 +1,7 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.mapper.Array;
import org.junit.jupiter.api.Test;
@ -8,26 +9,26 @@ 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;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.mapper.PatchableMapWrapper.entry;
import static org.assertj.core.api.Assertions.assertThat;
class HsEMailAddressHostingAssetValidatorUnitTest {
final static HsHostingAssetEntity domainSetup = HsHostingAssetEntity.builder()
final static HsHostingAssetRealEntity domainSetup = HsHostingAssetRealEntity.builder()
.type(DOMAIN_MBOX_SETUP)
.identifier("example.org")
.build();
final static HsHostingAssetEntity domainMboxSetup = HsHostingAssetEntity.builder()
final static HsHostingAssetRealEntity domainMboxSetup = HsHostingAssetRealEntity.builder()
.type(DOMAIN_MBOX_SETUP)
.identifier("example.org|MBOX")
.parentAsset(domainSetup)
.build();
static HsHostingAssetEntity.HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(EMAIL_ADDRESS)
.parentAsset(domainMboxSetup)
.identifier("old-local-part@example.org")
@ -173,9 +174,9 @@ class HsEMailAddressHostingAssetValidatorUnitTest {
void validatesInvalidReferences() {
// given
final var emailAddressHostingAssetEntity = validEntityBuilder()
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.assignedToAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.assignedToAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(emailAddressHostingAssetEntity.getType());

View File

@ -1,16 +1,16 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.mapper.Array;
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;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
import static org.assertj.core.api.Assertions.assertThat;
class HsEMailAliasHostingAssetValidatorUnitTest {
@ -28,9 +28,9 @@ class HsEMailAliasHostingAssetValidatorUnitTest {
@Test
void acceptsValidEntity() {
// given
final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder()
final var emailAliasHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(EMAIL_ALIAS)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("xyz00-office")
.config(Map.ofEntries(
entry("target", Array.of(
@ -54,9 +54,9 @@ class HsEMailAliasHostingAssetValidatorUnitTest {
@Test
void rejectsInvalidConfig() {
// given
final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder()
final var emailAliasHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(EMAIL_ALIAS)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("xyz00-office")
.config(Map.ofEntries(
entry("target", Array.of(
@ -83,9 +83,9 @@ class HsEMailAliasHostingAssetValidatorUnitTest {
@Test
void rejectsEmptyTargetArray() {
// given
final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder()
final var emailAliasHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(EMAIL_ALIAS)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("xyz00-office")
.config(Map.ofEntries(
entry("target", new String[0])
@ -104,9 +104,9 @@ class HsEMailAliasHostingAssetValidatorUnitTest {
@Test
void rejectsInvalidIndentifier() {
// given
final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder()
final var emailAliasHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(EMAIL_ALIAS)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("abc00-office")
.config(Map.ofEntries(
entry("target", Array.of("office@example.com"))
@ -125,11 +125,11 @@ class HsEMailAliasHostingAssetValidatorUnitTest {
@Test
void validatesInvalidReferences() {
// given
final var emailAliasHostingAssetEntity = HsHostingAssetEntity.builder()
final var emailAliasHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(EMAIL_ALIAS)
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.assignedToAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.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")
.config(Map.ofEntries(
entry("target", Array.of("office@example.com"))

View File

@ -1,9 +1,9 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
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 org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@ -20,8 +20,8 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsIPv4NumberHostingAssetValidatorUnitTest {
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(IPV4_NUMBER)
.identifier("83.223.95.145");
}
@ -69,7 +69,7 @@ class HsIPv4NumberHostingAssetValidatorUnitTest {
void acceptsValidReferencedEntity(final HsHostingAssetType givenAssignedToAssetType) {
// given
final var ipNumberHostingAssetEntity = validEntityBuilder()
.assignedToAsset(HsHostingAssetEntity.builder().type(givenAssignedToAssetType).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(givenAssignedToAssetType).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(ipNumberHostingAssetEntity.getType());
@ -84,9 +84,9 @@ class HsIPv4NumberHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var ipNumberHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(UNIX_USER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(UNIX_USER).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(ipNumberHostingAssetEntity.getType());

View File

@ -1,9 +1,9 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
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 org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@ -20,8 +20,8 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsIPv6NumberHostingAssetValidatorUnitTest {
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(IPV6_NUMBER)
.identifier("2001:db8:3333:4444:5555:6666:7777:8888");
}
@ -69,7 +69,7 @@ class HsIPv6NumberHostingAssetValidatorUnitTest {
void acceptsValidReferencedEntity(final HsHostingAssetType givenAssignedToAssetType) {
// given
final var ipNumberHostingAssetEntity = validEntityBuilder()
.assignedToAsset(HsHostingAssetEntity.builder().type(givenAssignedToAssetType).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(givenAssignedToAssetType).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(ipNumberHostingAssetEntity.getType());
@ -84,9 +84,9 @@ class HsIPv6NumberHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var ipNumberHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(UNIX_USER).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(UNIX_USER).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(ipNumberHostingAssetEntity.getType());

View File

@ -1,15 +1,16 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
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;
@ -19,12 +20,12 @@ class HsManagedServerHostingAssetValidatorUnitTest {
@Test
void validatesProperties() {
// given
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_SERVER)
.identifier("vm1234")
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM)
.parentAsset(HsHostingAssetEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(CLOUD_SERVER).build())
.bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.config(Map.ofEntries(
entry("monit_max_hdd_usage", "90"),
entry("monit_max_cpu_usage", 2),
@ -48,10 +49,10 @@ class HsManagedServerHostingAssetValidatorUnitTest {
@Test
void validatesInvalidIdentifier() {
// given
final var mangedServerHostingAssetEntity = HsHostingAssetEntity.builder()
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());
@ -66,12 +67,12 @@ class HsManagedServerHostingAssetValidatorUnitTest {
@Test
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = HsHostingAssetEntity.builder()
final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_SERVER)
.identifier("xyz00")
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM)
.parentAsset(HsHostingAssetEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(MANAGED_SERVER).build())
.bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,10 +1,15 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.EntityManagerMock;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
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;
@ -13,12 +18,13 @@ import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static org.assertj.core.api.Assertions.assertThat;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.TEST_PROJECT;
import static net.hostsharing.hsadminng.hs.booking.project.TestHsBookingProject.PROJECT_TEST_ENTITY;
@ExtendWith(MockitoExtension.class)
class HsManagedWebspaceHostingAssetValidatorUnitTest {
final HsBookingItemEntity managedServerBookingItem = HsBookingItemEntity.builder()
.project(TEST_PROJECT)
final HsBookingItemRealEntity managedServerBookingItem = HsBookingItemRealEntity.builder()
.project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.MANAGED_SERVER)
.caption("Test Managed-Server")
.resources(Map.ofEntries(
@ -30,12 +36,12 @@ 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();
final HsHostingAssetEntity mangedServerAssetEntity = HsHostingAssetEntity.builder()
final HsHostingAssetRealEntity mangedServerAssetEntity = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_SERVER)
.bookingItem(managedServerBookingItem)
.identifier("vm1234")
@ -45,7 +51,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
entry("monit_max_ram_usage", 90)
))
.build();
final HsHostingAssetEntity cloudServerAssetEntity = HsHostingAssetEntity.builder()
final HsHostingAssetRealEntity cloudServerAssetEntity = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.CLOUD_SERVER)
.bookingItem(cloudServerBookingItem)
.identifier("vm1234")
@ -60,9 +66,9 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void acceptsAlienIdentifierPrefixForPreExistingEntity() {
// given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
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())
@ -70,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();
@ -82,9 +90,9 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void validatesIdentifierAndReferencedEntities() {
// given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
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();
@ -100,9 +108,9 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void validatesUnknownProperties() {
// given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
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(
@ -121,23 +129,25 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void validatesValidEntity() {
// given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder()
.bookingItem(HsBookingItemRealEntity.builder()
.type(HsBookingItemType.MANAGED_WEBSPACE)
.project(TEST_PROJECT)
.project(PROJECT_TEST_ENTITY)
.caption("some ManagedWebspace")
.resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250)))
.build())
.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();
@ -147,15 +157,15 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void rejectsInvalidEntityReferences() {
// given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
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)))
.build())
.parentAsset(cloudServerAssetEntity)
.assignedToAsset(HsHostingAssetEntity.builder().type(CLOUD_SERVER).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.identifier("abc00")
.build();

View File

@ -1,33 +1,38 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.EntityManagerMock;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
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.HashMap;
import java.util.stream.Stream;
import static java.util.Map.ofEntries;
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.MARIADB_DATABASE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_INSTANCE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_USER;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
private static final HsHostingAssetEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetEntity.builder()
private static final HsHostingAssetRealEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetRealEntity.builder()
.type(MARIADB_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|MariaDB.default")
.caption("some valid test MariaDB-Instance")
.build();
private static final HsHostingAssetEntity GIVEN_MARIADB_USER = HsHostingAssetEntity.builder()
private static final HsHostingAssetRealEntity GIVEN_MARIADB_USER = HsHostingAssetRealEntity.builder()
.type(MARIADB_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.assignedToAsset(GIVEN_MARIADB_INSTANCE)
.identifier("xyz00_temp")
.caption("some valid test MariaDB-User")
@ -36,8 +41,8 @@ class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
)))
.build();
private static HsHostingAssetEntityBuilder givenValidMariaDbDatabaseBuilder() {
return HsHostingAssetEntity.builder()
private static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder givenValidMariaDbDatabaseBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(MARIADB_DATABASE)
.parentAsset(GIVEN_MARIADB_USER)
.identifier("MAD|xyz00_temp")
@ -66,12 +71,13 @@ class HsMariaDbDatabaseHostingAssetValidatorUnitTest {
// given
final var givenMariaDbUserHostingAsset = givenValidMariaDbDatabaseBuilder().build();
final var validator = HostingAssetEntityValidatorRegistry.forType(givenMariaDbUserHostingAsset.getType());
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = Stream.concat(
final var result = HsEntityValidator.doWithEntityManager(em, () -> Stream.concat(
validator.validateEntity(givenMariaDbUserHostingAsset).stream(),
validator.validateContext(givenMariaDbUserHostingAsset).stream()
).toList();
).toList());
// then
assertThat(result).isEmpty();

View File

@ -1,28 +1,28 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.junit.jupiter.api.Test;
import java.util.Map;
import static java.util.Map.entry;
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_SMTP_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_INSTANCE;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsMariaDbInstanceHostingAssetValidator.DEFAULT_INSTANCE_IDENTIFIER_SUFFIX;
import static org.assertj.core.api.Assertions.assertThat;
class HsMariaDbInstanceHostingAssetValidatorUnitTest {
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(MARIADB_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.identifier(TEST_MANAGED_SERVER_HOSTING_ASSET.getIdentifier() + DEFAULT_INSTANCE_IDENTIFIER_SUFFIX);
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY.getIdentifier() + DEFAULT_INSTANCE_IDENTIFIER_SUFFIX);
}
@Test
@ -80,9 +80,9 @@ class HsMariaDbInstanceHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,36 +1,43 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.EntityManagerMock;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
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;
import static java.util.Map.ofEntries;
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.MARIADB_INSTANCE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_USER;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsMariaDbUserHostingAssetValidatorUnitTest {
private static final HsHostingAssetEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetEntity.builder()
private static final HsHostingAssetRealEntity GIVEN_MARIADB_INSTANCE = HsHostingAssetRealEntity.builder()
.type(MARIADB_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|MariaDB.default")
.caption("some valid test MariaDB-Instance")
.build();
private EntityManager em = null; // not actually needed in these test cases
@Mock
private EntityManager em;
private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() {
return HsHostingAssetEntity.builder()
private static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> givenValidMariaDbUserBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(MARIADB_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.assignedToAsset(GIVEN_MARIADB_INSTANCE)
.identifier("MAU|xyz00_temp")
.caption("some valid test MariaDB-User")
@ -74,12 +81,13 @@ class HsMariaDbUserHostingAssetValidatorUnitTest {
// given
final var givenMariaDbUserHostingAsset = givenValidMariaDbUserBuilder().build();
final var validator = HostingAssetEntityValidatorRegistry.forType(givenMariaDbUserHostingAsset.getType());
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = Stream.concat(
final var result = HsEntityValidator.doWithEntityManager(em, () -> Stream.concat(
validator.validateEntity(givenMariaDbUserHostingAsset).stream(),
validator.validateContext(givenMariaDbUserHostingAsset).stream()
).toList();
).toList());
// then
assertThat(result).isEmpty();

View File

@ -1,35 +1,40 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.EntityManagerMock;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
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.HashMap;
import java.util.stream.Stream;
import static java.util.Map.ofEntries;
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.PGSQL_DATABASE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_INSTANCE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_USER;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
private static final HsHostingAssetEntity GIVEN_PGSQL_INSTANCE = HsHostingAssetEntity.builder()
private static final HsHostingAssetRealEntity GIVEN_PGSQL_INSTANCE = HsHostingAssetRealEntity.builder()
.type(PGSQL_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|PgSql.default")
.caption("some valid test PgSql-Instance")
.build();
private static final HsHostingAssetEntity GIVEN_PGSQL_USER = HsHostingAssetEntity.builder()
private static final HsHostingAssetRealEntity GIVEN_PGSQL_USER = HsHostingAssetRealEntity.builder()
.type(PGSQL_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.assignedToAsset(GIVEN_PGSQL_INSTANCE)
.identifier("xyz00_user")
.caption("some valid test PgSql-User")
@ -38,8 +43,8 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
)))
.build();
private static HsHostingAssetEntityBuilder givenValidPgSqlDatabaseBuilder() {
return HsHostingAssetEntity.builder()
private static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> givenValidPgSqlDatabaseBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(PGSQL_DATABASE)
.parentAsset(GIVEN_PGSQL_USER)
.identifier("PGD|xyz00_db")
@ -68,12 +73,13 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
// given
final var givenPgSqlUserHostingAsset = givenValidPgSqlDatabaseBuilder().build();
final var validator = HostingAssetEntityValidatorRegistry.forType(givenPgSqlUserHostingAsset.getType());
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = Stream.concat(
final var result = HsEntityValidator.doWithEntityManager(em, () -> Stream.concat(
validator.validateEntity(givenPgSqlUserHostingAsset).stream(),
validator.validateContext(givenPgSqlUserHostingAsset).stream()
).toList();
).toList());
// then
assertThat(result).isEmpty();
@ -83,9 +89,9 @@ class HsPostgreSqlDatabaseHostingAssetValidatorUnitTest {
void rejectsInvalidReferences() {
// given
final var givenPgSqlUserHostingAsset = givenValidPgSqlDatabaseBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(PGSQL_INSTANCE).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(PGSQL_INSTANCE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(PGSQL_INSTANCE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(PGSQL_INSTANCE).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(givenPgSqlUserHostingAsset.getType());

View File

@ -1,9 +1,9 @@
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.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import org.junit.jupiter.api.Test;
import java.util.Map;
@ -12,17 +12,17 @@ import static java.util.Map.entry;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_SMTP_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_INSTANCE;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetTestEntities.MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsMariaDbInstanceHostingAssetValidator.DEFAULT_INSTANCE_IDENTIFIER_SUFFIX;
import static org.assertj.core.api.Assertions.assertThat;
class HsPostgreSqlInstanceHostingAssetValidatorUnitTest {
static HsHostingAssetEntityBuilder validEntityBuilder() {
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(MARIADB_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.identifier(TEST_MANAGED_SERVER_HOSTING_ASSET.getIdentifier() + DEFAULT_INSTANCE_IDENTIFIER_SUFFIX);
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY.getIdentifier() + DEFAULT_INSTANCE_IDENTIFIER_SUFFIX);
}
@Test
@ -80,9 +80,9 @@ class HsPostgreSqlInstanceHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() {
// given
final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).build())
.bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.assignedToAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).build())
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,8 +1,10 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hash.HashGenerator;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity.HsHostingAssetEntityBuilder;
import net.hostsharing.hsadminng.hs.hosting.asset.EntityManagerMock;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
@ -12,28 +14,28 @@ import java.util.HashMap;
import java.util.stream.Stream;
import static java.util.Map.ofEntries;
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.PGSQL_INSTANCE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.PGSQL_USER;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_SERVER_HOSTING_ASSET;
import static net.hostsharing.hsadminng.hs.hosting.asset.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
import static org.assertj.core.api.Assertions.assertThat;
class HsPostgreSqlUserHostingAssetValidatorUnitTest {
private static final HsHostingAssetEntity GIVEN_PGSQL_INSTANCE = HsHostingAssetEntity.builder()
private static final HsHostingAssetRealEntity GIVEN_PGSQL_INSTANCE = HsHostingAssetRealEntity.builder()
.type(PGSQL_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|PgSql.default")
.caption("some valid test PgSql-Instance")
.build();
private EntityManager em = null; // not actually needed in these test cases
private static HsHostingAssetEntityBuilder givenValidMariaDbUserBuilder() {
return HsHostingAssetEntity.builder()
private static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> givenValidMariaDbUserBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(PGSQL_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.assignedToAsset(GIVEN_PGSQL_INSTANCE)
.identifier("PGU|xyz00_temp")
.caption("some valid test PgSql-User")
@ -77,12 +79,13 @@ class HsPostgreSqlUserHostingAssetValidatorUnitTest {
// given
final var givenMariaDbUserHostingAsset = givenValidMariaDbUserBuilder().build();
final var validator = HostingAssetEntityValidatorRegistry.forType(givenMariaDbUserHostingAsset.getType());
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = Stream.concat(
final var result = HsEntityValidator.doWithEntityManager(em, () -> Stream.concat(
validator.validateEntity(givenMariaDbUserHostingAsset).stream(),
validator.validateContext(givenMariaDbUserHostingAsset).stream()
).toList();
).toList());
// then
assertThat(result).isEmpty();

View File

@ -1,8 +1,11 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hash.HashGenerator;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.EntityManagerMock;
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.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -15,8 +18,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;
@ -27,21 +30,27 @@ import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class)
class HsUnixUserHostingAssetValidatorUnitTest {
private final HsHostingAssetEntity TEST_MANAGED_SERVER_HOSTING_ASSET = HsHostingAssetEntity.builder()
private final HsHostingAssetRealEntity TEST_MANAGED_SERVER_HOSTING_ASSET_REAL_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();
private final HsHostingAssetEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET = HsHostingAssetEntity.builder()
private final HsHostingAssetRealEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET_REAL_ENTITY = HsHostingAssetRealEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET)
.bookingItem(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00")
.build();
private final HsHostingAssetEntity GIVEN_VALID_UNIX_USER_HOSTING_ASSET = HsHostingAssetEntity.builder()
private final HsHostingAssetRbacEntity TEST_MANAGED_WEBSPACE_HOSTING_ASSET_RBAC_ENTITY = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE)
.bookingItem(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00")
.build();
private final HsHostingAssetRbacEntity GIVEN_VALID_UNIX_USER_HOSTING_ASSET = HsHostingAssetRbacEntity.builder()
.type(UNIX_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00-temp")
.caption("some valid test UnixUser")
.config(new HashMap<>(ofEntries(
@ -89,12 +98,13 @@ class HsUnixUserHostingAssetValidatorUnitTest {
// given
final var unixUserHostingAsset = GIVEN_VALID_UNIX_USER_HOSTING_ASSET;
final var validator = HostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when
final var result = Stream.concat(
final var result = HsEntityValidator.doWithEntityManager(em, () -> Stream.concat(
validator.validateEntity(unixUserHostingAsset).stream(),
validator.validateContext(unixUserHostingAsset).stream()
).toList();
).toList());
// then
assertThat(result).isEmpty();
@ -103,9 +113,9 @@ class HsUnixUserHostingAssetValidatorUnitTest {
@Test
void validatesUnixUserProperties() {
// given
final var unixUserHostingAsset = HsHostingAssetEntity.builder()
final var unixUserHostingAsset = HsHostingAssetRbacEntity.builder()
.type(UNIX_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00-temp")
.caption("some test UnixUser with invalid properties")
.config(ofEntries(
@ -140,9 +150,9 @@ class HsUnixUserHostingAssetValidatorUnitTest {
@Test
void validatesInvalidIdentifier() {
// given
final var unixUserHostingAsset = HsHostingAssetEntity.builder()
final var unixUserHostingAsset = HsHostingAssetRbacEntity.builder()
.type(UNIX_USER)
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).identifier("abc00").build())
.parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).identifier("abc00").build())
.identifier("xyz99-temp")
.build();
final var validator = HostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());

View File

@ -1,114 +0,0 @@
package net.hostsharing.hsadminng.hs.migration;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
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;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
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 java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Builder
@Entity
@Table(name = "hs_hosting_asset")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class HsHostingAssetRealEntity implements HsHostingAsset {
@Id
@GeneratedValue
private UUID uuid;
@Version
private int version;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "bookingitemuuid")
private HsBookingItemEntity bookingItem;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parentassetuuid")
private HsHostingAssetRealEntity parentAsset;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "assignedtoassetuuid")
private HsHostingAssetRealEntity assignedToAsset;
@Column(name = "type")
@Enumerated(EnumType.STRING)
private HsHostingAssetType type;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "alarmcontactuuid")
private HsOfficeContactRealEntity alarmContact;
@OneToMany(cascade = CascadeType.REFRESH, orphanRemoval = true, fetch = FetchType.LAZY)
@JoinColumn(name = "parentassetuuid", referencedColumnName = "uuid")
private List<HsHostingAssetRealEntity> subHostingAssets;
@Column(name = "identifier")
private String identifier; // e.g. vm1234, xyz00, example.org, xyz00_abc
@Column(name = "caption")
private String caption;
@Builder.Default
@Setter(AccessLevel.NONE)
@Type(JsonType.class)
@Column(columnDefinition = "config")
private Map<String, Object> config = new HashMap<>();
@Transient
private PatchableMapWrapper<Object> configWrapper;
@Transient
private boolean isLoaded;
@PostLoad
public void markAsLoaded() {
this.isLoaded = true;
}
public PatchableMapWrapper<Object> getConfig() {
return PatchableMapWrapper.of(configWrapper, (newWrapper) -> {configWrapper = newWrapper;}, config);
}
@Override
public PatchableMapWrapper<Object> directProps() {
return getConfig();
}
@Override
public String toString() {
return stringify.using(HsHostingAssetRealEntity.class).apply(this);
}
}

View File

@ -6,10 +6,12 @@ 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.HsBookingProjectEntity;
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 net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry;
@ -130,8 +132,8 @@ public class ImportHostingAssets extends ImportOfficeData {
record Hive(int hive_id, String hive_name, int inet_addr_id, AtomicReference<HsHostingAssetRealEntity> serverRef) {}
static Map<Integer, HsBookingProjectEntity> bookingProjects = new WriteOnceMap<>();
static Map<Integer, HsBookingItemEntity> bookingItems = new WriteOnceMap<>();
static Map<Integer, HsBookingProjectRealEntity> bookingProjects = new WriteOnceMap<>();
static Map<Integer, HsBookingItem> bookingItems = new WriteOnceMap<>();
static Map<Integer, Hive> hives = new WriteOnceMap<>();
static Map<Integer, HsHostingAssetRealEntity> ipNumberAssets = new WriteOnceMap<>();
@ -157,7 +159,7 @@ public class ImportHostingAssets extends ImportOfficeData {
@Order(11010)
void createBookingProjects() {
debitors.forEach((id, debitor) -> {
bookingProjects.put(id, HsBookingProjectEntity.builder()
bookingProjects.put(id, HsBookingProjectRealEntity.builder()
.caption(debitor.getDefaultPrefix() + " default project")
.debitor(em.find(HsBookingDebitorEntity.class, debitor.getUuid()))
.build());
@ -182,11 +184,11 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(5, ipNumberAssets)).isEqualToIgnoringWhitespace("""
{
363=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.34),
381=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.52),
401=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.72),
402=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.73),
433=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.104)
363=HsHostingAsset(IPV4_NUMBER, 83.223.95.34),
381=HsHostingAsset(IPV4_NUMBER, 83.223.95.52),
401=HsHostingAsset(IPV4_NUMBER, 83.223.95.72),
402=HsHostingAsset(IPV4_NUMBER, 83.223.95.73),
433=HsHostingAsset(IPV4_NUMBER, 83.223.95.104)
}
""");
}
@ -251,15 +253,15 @@ public class ImportHostingAssets extends ImportOfficeData {
""");
assertThat(firstOfEach(9, packetAssets)).isEqualToIgnoringWhitespace("""
{
10630=HsHostingAssetRealEntity(MANAGED_WEBSPACE, hsh00, HA hsh00, MANAGED_SERVER:vm1050, D-1000000:hsh default project:BI hsh00),
10968=HsHostingAssetRealEntity(MANAGED_SERVER, vm1061, HA vm1061, D-1015200:rar default project:BI vm1061),
10978=HsHostingAssetRealEntity(MANAGED_SERVER, vm1050, HA vm1050, D-1000000:hsh default project:BI vm1050),
11061=HsHostingAssetRealEntity(MANAGED_SERVER, vm1068, HA vm1068, D-1000300:mim default project:BI vm1068),
11094=HsHostingAssetRealEntity(MANAGED_WEBSPACE, lug00, HA lug00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI lug00),
11111=HsHostingAssetRealEntity(MANAGED_WEBSPACE, xyz68, HA xyz68, MANAGED_SERVER:vm1068, D-1000000:vm1068 Monitor:BI xyz68),
11112=HsHostingAssetRealEntity(MANAGED_WEBSPACE, mim00, HA mim00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI mim00),
11447=HsHostingAssetRealEntity(MANAGED_SERVER, vm1093, HA vm1093, D-1000000:hsh default project:BI vm1093),
19959=HsHostingAssetRealEntity(MANAGED_WEBSPACE, dph00, HA dph00, MANAGED_SERVER:vm1093, D-1101900:dph default project:BI dph00)
10630=HsHostingAsset(MANAGED_WEBSPACE, hsh00, HA hsh00, MANAGED_SERVER:vm1050, D-1000000:hsh default project:BI hsh00),
10968=HsHostingAsset(MANAGED_SERVER, vm1061, HA vm1061, D-1015200:rar default project:BI vm1061),
10978=HsHostingAsset(MANAGED_SERVER, vm1050, HA vm1050, D-1000000:hsh default project:BI vm1050),
11061=HsHostingAsset(MANAGED_SERVER, vm1068, HA vm1068, D-1000300:mim default project:BI vm1068),
11094=HsHostingAsset(MANAGED_WEBSPACE, lug00, HA lug00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI lug00),
11111=HsHostingAsset(MANAGED_WEBSPACE, xyz68, HA xyz68, MANAGED_SERVER:vm1068, D-1000000:vm1068 Monitor:BI xyz68),
11112=HsHostingAsset(MANAGED_WEBSPACE, mim00, HA mim00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI mim00),
11447=HsHostingAsset(MANAGED_SERVER, vm1093, HA vm1093, D-1000000:hsh default project:BI vm1093),
19959=HsHostingAsset(MANAGED_WEBSPACE, dph00, HA dph00, MANAGED_SERVER:vm1093, D-1101900:dph default project:BI dph00)
}
""");
}
@ -283,13 +285,13 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(7, packetAssets))
.isEqualToIgnoringWhitespace("""
{
10630=HsHostingAssetRealEntity(MANAGED_WEBSPACE, hsh00, HA hsh00, MANAGED_SERVER:vm1050, D-1000000:hsh default project:BI hsh00),
10968=HsHostingAssetRealEntity(MANAGED_SERVER, vm1061, HA vm1061, D-1015200:rar default project:BI vm1061),
10978=HsHostingAssetRealEntity(MANAGED_SERVER, vm1050, HA vm1050, D-1000000:hsh default project:BI vm1050),
11061=HsHostingAssetRealEntity(MANAGED_SERVER, vm1068, HA vm1068, D-1000300:mim default project:BI vm1068),
11094=HsHostingAssetRealEntity(MANAGED_WEBSPACE, lug00, HA lug00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI lug00),
11111=HsHostingAssetRealEntity(MANAGED_WEBSPACE, xyz68, HA xyz68, MANAGED_SERVER:vm1068, D-1000000:vm1068 Monitor:BI xyz68),
11112=HsHostingAssetRealEntity(MANAGED_WEBSPACE, mim00, HA mim00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI mim00)
10630=HsHostingAsset(MANAGED_WEBSPACE, hsh00, HA hsh00, MANAGED_SERVER:vm1050, D-1000000:hsh default project:BI hsh00),
10968=HsHostingAsset(MANAGED_SERVER, vm1061, HA vm1061, D-1015200:rar default project:BI vm1061),
10978=HsHostingAsset(MANAGED_SERVER, vm1050, HA vm1050, D-1000000:hsh default project:BI vm1050),
11061=HsHostingAsset(MANAGED_SERVER, vm1068, HA vm1068, D-1000300:mim default project:BI vm1068),
11094=HsHostingAsset(MANAGED_WEBSPACE, lug00, HA lug00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI lug00),
11111=HsHostingAsset(MANAGED_WEBSPACE, xyz68, HA xyz68, MANAGED_SERVER:vm1068, D-1000000:vm1068 Monitor:BI xyz68),
11112=HsHostingAsset(MANAGED_WEBSPACE, mim00, HA mim00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI mim00)
}
""");
assertThat(firstOfEachType(
@ -331,21 +333,21 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(15, unixUserAssets)).isEqualToIgnoringWhitespace("""
{
5803=HsHostingAssetRealEntity(UNIX_USER, lug00, LUGs, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102090}),
5805=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.1, Paul Klemm, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102091}),
5809=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.2, Walter Müller, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 8, "SSD soft quota": 4, "locked": false, "shell": "/bin/bash", "userid": 102093}),
5811=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.a, LUG OLA - POP a, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102094}),
5813=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.b, LUG OLA - POP b, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102095}),
5835=HsHostingAssetRealEntity(UNIX_USER, lug00-test, Test, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 1024, "SSD soft quota": 1024, "locked": false, "shell": "/usr/bin/passwd", "userid": 102106}),
5961=HsHostingAssetRealEntity(UNIX_USER, xyz68, Monitoring h68, MANAGED_WEBSPACE:xyz68, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102141}),
5964=HsHostingAssetRealEntity(UNIX_USER, mim00, Michael Mellis, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102147}),
5966=HsHostingAssetRealEntity(UNIX_USER, mim00-1981, Jahrgangstreffen 1981, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 256, "SSD soft quota": 128, "locked": false, "shell": "/bin/bash", "userid": 102148}),
5990=HsHostingAssetRealEntity(UNIX_USER, mim00-mail, Mailbox, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102160}),
6705=HsHostingAssetRealEntity(UNIX_USER, hsh00-mim, Michael Mellis, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 10003}),
6824=HsHostingAssetRealEntity(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 10000}),
7846=HsHostingAssetRealEntity(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 110568}),
9546=HsHostingAssetRealEntity(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110593}),
9596=HsHostingAssetRealEntity(UNIX_USER, dph00-dph, Domain admin, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110594})
5803=HsHostingAsset(UNIX_USER, lug00, LUGs, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102090}),
5805=HsHostingAsset(UNIX_USER, lug00-wla.1, Paul Klemm, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102091}),
5809=HsHostingAsset(UNIX_USER, lug00-wla.2, Walter Müller, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 8, "SSD soft quota": 4, "locked": false, "shell": "/bin/bash", "userid": 102093}),
5811=HsHostingAsset(UNIX_USER, lug00-ola.a, LUG OLA - POP a, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102094}),
5813=HsHostingAsset(UNIX_USER, lug00-ola.b, LUG OLA - POP b, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/usr/bin/passwd", "userid": 102095}),
5835=HsHostingAsset(UNIX_USER, lug00-test, Test, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 1024, "SSD soft quota": 1024, "locked": false, "shell": "/usr/bin/passwd", "userid": 102106}),
5961=HsHostingAsset(UNIX_USER, xyz68, Monitoring h68, MANAGED_WEBSPACE:xyz68, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102141}),
5964=HsHostingAsset(UNIX_USER, mim00, Michael Mellis, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102147}),
5966=HsHostingAsset(UNIX_USER, mim00-1981, Jahrgangstreffen 1981, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 256, "SSD soft quota": 128, "locked": false, "shell": "/bin/bash", "userid": 102148}),
5990=HsHostingAsset(UNIX_USER, mim00-mail, Mailbox, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102160}),
6705=HsHostingAsset(UNIX_USER, hsh00-mim, Michael Mellis, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 10003}),
6824=HsHostingAsset(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 10000}),
7846=HsHostingAsset(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/false", "userid": 110568}),
9546=HsHostingAsset(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110593}),
9596=HsHostingAsset(UNIX_USER, dph00-dph, Domain admin, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110594})
}
""");
}
@ -368,15 +370,15 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(15, emailAliasAssets)).isEqualToIgnoringWhitespace("""
{
2403=HsHostingAssetRealEntity(EMAIL_ALIAS, lug00, lug00, MANAGED_WEBSPACE:lug00, {"target": [ "michael.mellis@example.com" ]}),
2405=HsHostingAssetRealEntity(EMAIL_ALIAS, lug00-wla-listar, lug00-wla-listar, MANAGED_WEBSPACE:lug00, {"target": [ "|/home/pacs/lug00/users/in/mailinglist/listar" ]}),
2429=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00, mim00, MANAGED_WEBSPACE:mim00, {"target": [ "mim12-mi@mim12.hostsharing.net" ]}),
2431=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-abruf, mim00-abruf, MANAGED_WEBSPACE:mim00, {"target": [ "michael.mellis@hostsharing.net" ]}),
2449=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-hhfx, mim00-hhfx, MANAGED_WEBSPACE:mim00, {"target": [ "mim00-hhfx", "|/usr/bin/formail -I 'Reply-To: hamburger-fx@example.net' | /usr/lib/sendmail mim00-hhfx-l" ]}),
2451=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-hhfx-l, mim00-hhfx-l, MANAGED_WEBSPACE:mim00, {"target": [ ":include:/home/pacs/mim00/etc/hhfx.list" ]}),
2454=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-dev.null, mim00-dev.null, MANAGED_WEBSPACE:mim00, {"target": [ "/dev/null" ]}),
2455=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-1_with_space, mim00-1_with_space, MANAGED_WEBSPACE:mim00, {"target": [ "|/home/pacs/mim00/install/corpslistar/listar" ]}),
2456=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-1_with_single_quotes, mim00-1_with_single_quotes, MANAGED_WEBSPACE:mim00, {"target": [ "|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern" ]})
2403=HsHostingAsset(EMAIL_ALIAS, lug00, lug00, MANAGED_WEBSPACE:lug00, {"target": [ "michael.mellis@example.com" ]}),
2405=HsHostingAsset(EMAIL_ALIAS, lug00-wla-listar, lug00-wla-listar, MANAGED_WEBSPACE:lug00, {"target": [ "|/home/pacs/lug00/users/in/mailinglist/listar" ]}),
2429=HsHostingAsset(EMAIL_ALIAS, mim00, mim00, MANAGED_WEBSPACE:mim00, {"target": [ "mim12-mi@mim12.hostsharing.net" ]}),
2431=HsHostingAsset(EMAIL_ALIAS, mim00-abruf, mim00-abruf, MANAGED_WEBSPACE:mim00, {"target": [ "michael.mellis@hostsharing.net" ]}),
2449=HsHostingAsset(EMAIL_ALIAS, mim00-hhfx, mim00-hhfx, MANAGED_WEBSPACE:mim00, {"target": [ "mim00-hhfx", "|/usr/bin/formail -I 'Reply-To: hamburger-fx@example.net' | /usr/lib/sendmail mim00-hhfx-l" ]}),
2451=HsHostingAsset(EMAIL_ALIAS, mim00-hhfx-l, mim00-hhfx-l, MANAGED_WEBSPACE:mim00, {"target": [ ":include:/home/pacs/mim00/etc/hhfx.list" ]}),
2454=HsHostingAsset(EMAIL_ALIAS, mim00-dev.null, mim00-dev.null, MANAGED_WEBSPACE:mim00, {"target": [ "/dev/null" ]}),
2455=HsHostingAsset(EMAIL_ALIAS, mim00-1_with_space, mim00-1_with_space, MANAGED_WEBSPACE:mim00, {"target": [ "|/home/pacs/mim00/install/corpslistar/listar" ]}),
2456=HsHostingAsset(EMAIL_ALIAS, mim00-1_with_single_quotes, mim00-1_with_single_quotes, MANAGED_WEBSPACE:mim00, {"target": [ "|/home/pacs/rir00/mailinglist/ecartis -r kybs06-intern" ]})
}
""");
}
@ -394,14 +396,14 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(8, dbInstanceAssets)).isEqualToIgnoringWhitespace("""
{
0=HsHostingAssetRealEntity(PGSQL_INSTANCE, vm1061|PgSql.default, vm1061-PostgreSQL default instance, MANAGED_SERVER:vm1061),
1=HsHostingAssetRealEntity(MARIADB_INSTANCE, vm1061|MariaDB.default, vm1061-MariaDB default instance, MANAGED_SERVER:vm1061),
2=HsHostingAssetRealEntity(PGSQL_INSTANCE, vm1050|PgSql.default, vm1050-PostgreSQL default instance, MANAGED_SERVER:vm1050),
3=HsHostingAssetRealEntity(MARIADB_INSTANCE, vm1050|MariaDB.default, vm1050-MariaDB default instance, MANAGED_SERVER:vm1050),
4=HsHostingAssetRealEntity(PGSQL_INSTANCE, vm1068|PgSql.default, vm1068-PostgreSQL default instance, MANAGED_SERVER:vm1068),
5=HsHostingAssetRealEntity(MARIADB_INSTANCE, vm1068|MariaDB.default, vm1068-MariaDB default instance, MANAGED_SERVER:vm1068),
6=HsHostingAssetRealEntity(PGSQL_INSTANCE, vm1093|PgSql.default, vm1093-PostgreSQL default instance, MANAGED_SERVER:vm1093),
7=HsHostingAssetRealEntity(MARIADB_INSTANCE, vm1093|MariaDB.default, vm1093-MariaDB default instance, MANAGED_SERVER:vm1093)
0=HsHostingAsset(PGSQL_INSTANCE, vm1061|PgSql.default, vm1061-PostgreSQL default instance, MANAGED_SERVER:vm1061),
1=HsHostingAsset(MARIADB_INSTANCE, vm1061|MariaDB.default, vm1061-MariaDB default instance, MANAGED_SERVER:vm1061),
2=HsHostingAsset(PGSQL_INSTANCE, vm1050|PgSql.default, vm1050-PostgreSQL default instance, MANAGED_SERVER:vm1050),
3=HsHostingAsset(MARIADB_INSTANCE, vm1050|MariaDB.default, vm1050-MariaDB default instance, MANAGED_SERVER:vm1050),
4=HsHostingAsset(PGSQL_INSTANCE, vm1068|PgSql.default, vm1068-PostgreSQL default instance, MANAGED_SERVER:vm1068),
5=HsHostingAsset(MARIADB_INSTANCE, vm1068|MariaDB.default, vm1068-MariaDB default instance, MANAGED_SERVER:vm1068),
6=HsHostingAsset(PGSQL_INSTANCE, vm1093|PgSql.default, vm1093-PostgreSQL default instance, MANAGED_SERVER:vm1093),
7=HsHostingAsset(MARIADB_INSTANCE, vm1093|MariaDB.default, vm1093-MariaDB default instance, MANAGED_SERVER:vm1093)
}
""");
}
@ -424,16 +426,16 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(10, dbUserAssets)).isEqualToIgnoringWhitespace("""
{
1857=HsHostingAssetRealEntity(PGSQL_USER, PGU|hsh00, hsh00, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$JDiZmaxU+O+ByArLY/CkYZ8HbOk0r/I8LyABnno5gQs=:NI3T500/63dzI1B07Jh3UtQGlukS6JxuS0XoxM/QgAc="}),
1858=HsHostingAssetRealEntity(MARIADB_USER, MAU|hsh00, hsh00, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*59067A36BA197AD0A47D74909296C5B002A0FB9F"}),
1859=HsHostingAssetRealEntity(PGSQL_USER, PGU|hsh00_vorstand, hsh00_vorstand, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$54Wh+OGx/GaIvAia+I3k78jHGhqmYwe4+iLssmH5zhk=:D4Gq1z2Li2BVSaZrz1azDrs6pwsIzhq4+suK1Hh6ZIg="}),
1860=HsHostingAssetRealEntity(PGSQL_USER, PGU|hsh00_hsadmin, hsh00_hsadmin, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$54Wh+OGx/GaIvAia+I3k78jHGhqmYwe4+iLssmH5zhk=:D4Gq1z2Li2BVSaZrz1azDrs6pwsIzhq4+suK1Hh6ZIg="}),
1861=HsHostingAssetRealEntity(PGSQL_USER, PGU|hsh00_hsadmin_ro, hsh00_hsadmin_ro, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$UhJnJJhmKANbcaG+izWK3rz5bmhhluSuiCJFlUmDVI8=:6AC4mbLfJGiGlEOWhpz9BivvMODhLLHOnRnnktJPgn8="}),
4908=HsHostingAssetRealEntity(MARIADB_USER, MAU|hsh00_mantis, hsh00_mantis, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*EA4C0889A22AAE66BBEBC88161E8CF862D73B44F"}),
4909=HsHostingAssetRealEntity(MARIADB_USER, MAU|hsh00_mantis_ro, hsh00_mantis_ro, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*B3BB6D0DA2EC01958616E9B3BCD2926FE8C38383"}),
4931=HsHostingAssetRealEntity(PGSQL_USER, PGU|hsh00_phpPgSqlAdmin, hsh00_phpPgSqlAdmin, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$UhJnJJhmKANbcaG+izWK3rz5bmhhluSuiCJFlUmDVI8=:6AC4mbLfJGiGlEOWhpz9BivvMODhLLHOnRnnktJPgn8="}),
4932=HsHostingAssetRealEntity(MARIADB_USER, MAU|hsh00_phpMyAdmin, hsh00_phpMyAdmin, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*3188720B1889EF5447C722629765F296F40257C2"}),
7520=HsHostingAssetRealEntity(MARIADB_USER, MAU|lug00_wla, lug00_wla, MANAGED_WEBSPACE:lug00, MARIADB_INSTANCE:vm1068|MariaDB.default, { "password": "*11667C0EAC42BF8B0295ABEDC7D2868A835E4DB5"})
1857=HsHostingAsset(PGSQL_USER, PGU|hsh00, hsh00, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$JDiZmaxU+O+ByArLY/CkYZ8HbOk0r/I8LyABnno5gQs=:NI3T500/63dzI1B07Jh3UtQGlukS6JxuS0XoxM/QgAc="}),
1858=HsHostingAsset(MARIADB_USER, MAU|hsh00, hsh00, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*59067A36BA197AD0A47D74909296C5B002A0FB9F"}),
1859=HsHostingAsset(PGSQL_USER, PGU|hsh00_vorstand, hsh00_vorstand, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$54Wh+OGx/GaIvAia+I3k78jHGhqmYwe4+iLssmH5zhk=:D4Gq1z2Li2BVSaZrz1azDrs6pwsIzhq4+suK1Hh6ZIg="}),
1860=HsHostingAsset(PGSQL_USER, PGU|hsh00_hsadmin, hsh00_hsadmin, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$54Wh+OGx/GaIvAia+I3k78jHGhqmYwe4+iLssmH5zhk=:D4Gq1z2Li2BVSaZrz1azDrs6pwsIzhq4+suK1Hh6ZIg="}),
1861=HsHostingAsset(PGSQL_USER, PGU|hsh00_hsadmin_ro, hsh00_hsadmin_ro, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$UhJnJJhmKANbcaG+izWK3rz5bmhhluSuiCJFlUmDVI8=:6AC4mbLfJGiGlEOWhpz9BivvMODhLLHOnRnnktJPgn8="}),
4908=HsHostingAsset(MARIADB_USER, MAU|hsh00_mantis, hsh00_mantis, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*EA4C0889A22AAE66BBEBC88161E8CF862D73B44F"}),
4909=HsHostingAsset(MARIADB_USER, MAU|hsh00_mantis_ro, hsh00_mantis_ro, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*B3BB6D0DA2EC01958616E9B3BCD2926FE8C38383"}),
4931=HsHostingAsset(PGSQL_USER, PGU|hsh00_phpPgSqlAdmin, hsh00_phpPgSqlAdmin, MANAGED_WEBSPACE:hsh00, PGSQL_INSTANCE:vm1050|PgSql.default, { "password": "SCRAM-SHA-256$4096:Zml4ZWQgc2FsdA==$UhJnJJhmKANbcaG+izWK3rz5bmhhluSuiCJFlUmDVI8=:6AC4mbLfJGiGlEOWhpz9BivvMODhLLHOnRnnktJPgn8="}),
4932=HsHostingAsset(MARIADB_USER, MAU|hsh00_phpMyAdmin, hsh00_phpMyAdmin, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*3188720B1889EF5447C722629765F296F40257C2"}),
7520=HsHostingAsset(MARIADB_USER, MAU|lug00_wla, lug00_wla, MANAGED_WEBSPACE:lug00, MARIADB_INSTANCE:vm1068|MariaDB.default, { "password": "*11667C0EAC42BF8B0295ABEDC7D2868A835E4DB5"})
}
""");
}
@ -456,16 +458,16 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(10, dbAssets)).isEqualToIgnoringWhitespace("""
{
1077=HsHostingAssetRealEntity(PGSQL_DATABASE, PGD|hsh00_vorstand, hsh00_vorstand, PGSQL_USER:PGU|hsh00_vorstand, {"encoding": "LATIN1"}),
1786=HsHostingAssetRealEntity(MARIADB_DATABASE, MAD|hsh00_addr, hsh00_addr, MARIADB_USER:MAU|hsh00, {"encoding": "latin1"}),
1805=HsHostingAssetRealEntity(MARIADB_DATABASE, MAD|hsh00_dba, hsh00_dba, MARIADB_USER:MAU|hsh00, {"encoding": "latin1"}),
1858=HsHostingAssetRealEntity(PGSQL_DATABASE, PGD|hsh00, hsh00, PGSQL_USER:PGU|hsh00, {"encoding": "LATIN1"}),
1860=HsHostingAssetRealEntity(PGSQL_DATABASE, PGD|hsh00_hsadmin, hsh00_hsadmin, PGSQL_USER:PGU|hsh00_hsadmin, {"encoding": "UTF8"}),
4908=HsHostingAssetRealEntity(MARIADB_DATABASE, MAD|hsh00_mantis, hsh00_mantis, MARIADB_USER:MAU|hsh00_mantis, {"encoding": "utf8"}),
4931=HsHostingAssetRealEntity(PGSQL_DATABASE, PGD|hsh00_phpPgSqlAdmin, hsh00_phpPgSqlAdmin, PGSQL_USER:PGU|hsh00_phpPgSqlAdmin, {"encoding": "UTF8"}),
4932=HsHostingAssetRealEntity(PGSQL_DATABASE, PGD|hsh00_phpPgSqlAdmin_new, hsh00_phpPgSqlAdmin_new, PGSQL_USER:PGU|hsh00_phpPgSqlAdmin, {"encoding": "UTF8"}),
4941=HsHostingAssetRealEntity(MARIADB_DATABASE, MAD|hsh00_phpMyAdmin, hsh00_phpMyAdmin, MARIADB_USER:MAU|hsh00_phpMyAdmin, {"encoding": "utf8"}),
4942=HsHostingAssetRealEntity(MARIADB_DATABASE, MAD|hsh00_phpMyAdmin_old, hsh00_phpMyAdmin_old, MARIADB_USER:MAU|hsh00_phpMyAdmin, {"encoding": "utf8"})
1077=HsHostingAsset(PGSQL_DATABASE, PGD|hsh00_vorstand, hsh00_vorstand, PGSQL_USER:PGU|hsh00_vorstand, {"encoding": "LATIN1"}),
1786=HsHostingAsset(MARIADB_DATABASE, MAD|hsh00_addr, hsh00_addr, MARIADB_USER:MAU|hsh00, {"encoding": "latin1"}),
1805=HsHostingAsset(MARIADB_DATABASE, MAD|hsh00_dba, hsh00_dba, MARIADB_USER:MAU|hsh00, {"encoding": "latin1"}),
1858=HsHostingAsset(PGSQL_DATABASE, PGD|hsh00, hsh00, PGSQL_USER:PGU|hsh00, {"encoding": "LATIN1"}),
1860=HsHostingAsset(PGSQL_DATABASE, PGD|hsh00_hsadmin, hsh00_hsadmin, PGSQL_USER:PGU|hsh00_hsadmin, {"encoding": "UTF8"}),
4908=HsHostingAsset(MARIADB_DATABASE, MAD|hsh00_mantis, hsh00_mantis, MARIADB_USER:MAU|hsh00_mantis, {"encoding": "utf8"}),
4931=HsHostingAsset(PGSQL_DATABASE, PGD|hsh00_phpPgSqlAdmin, hsh00_phpPgSqlAdmin, PGSQL_USER:PGU|hsh00_phpPgSqlAdmin, {"encoding": "UTF8"}),
4932=HsHostingAsset(PGSQL_DATABASE, PGD|hsh00_phpPgSqlAdmin_new, hsh00_phpPgSqlAdmin_new, PGSQL_USER:PGU|hsh00_phpPgSqlAdmin, {"encoding": "UTF8"}),
4941=HsHostingAsset(MARIADB_DATABASE, MAD|hsh00_phpMyAdmin, hsh00_phpMyAdmin, MARIADB_USER:MAU|hsh00_phpMyAdmin, {"encoding": "utf8"}),
4942=HsHostingAsset(MARIADB_DATABASE, MAD|hsh00_phpMyAdmin_old, hsh00_phpMyAdmin_old, MARIADB_USER:MAU|hsh00_phpMyAdmin, {"encoding": "utf8"})
}
""");
}
@ -499,71 +501,71 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(12, domainSetupAssets)).isEqualToIgnoringWhitespace("""
{
4531=HsHostingAssetRealEntity(DOMAIN_SETUP, l-u-g.org, l-u-g.org),
4532=HsHostingAssetRealEntity(DOMAIN_SETUP, linuxfanboysngirls.de, linuxfanboysngirls.de),
4534=HsHostingAssetRealEntity(DOMAIN_SETUP, lug-mars.de, lug-mars.de),
4581=HsHostingAssetRealEntity(DOMAIN_SETUP, 1981.ist-im-netz.de, 1981.ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de),
4587=HsHostingAssetRealEntity(DOMAIN_SETUP, mellis.de, mellis.de),
4589=HsHostingAssetRealEntity(DOMAIN_SETUP, ist-im-netz.de, ist-im-netz.de),
4600=HsHostingAssetRealEntity(DOMAIN_SETUP, waera.de, waera.de),
4604=HsHostingAssetRealEntity(DOMAIN_SETUP, xn--wra-qla.de, wära.de),
7662=HsHostingAssetRealEntity(DOMAIN_SETUP, dph-netzwerk.de, dph-netzwerk.de)
4531=HsHostingAsset(DOMAIN_SETUP, l-u-g.org, l-u-g.org),
4532=HsHostingAsset(DOMAIN_SETUP, linuxfanboysngirls.de, linuxfanboysngirls.de),
4534=HsHostingAsset(DOMAIN_SETUP, lug-mars.de, lug-mars.de),
4581=HsHostingAsset(DOMAIN_SETUP, 1981.ist-im-netz.de, 1981.ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de),
4587=HsHostingAsset(DOMAIN_SETUP, mellis.de, mellis.de),
4589=HsHostingAsset(DOMAIN_SETUP, ist-im-netz.de, ist-im-netz.de),
4600=HsHostingAsset(DOMAIN_SETUP, waera.de, waera.de),
4604=HsHostingAsset(DOMAIN_SETUP, xn--wra-qla.de, wära.de),
7662=HsHostingAsset(DOMAIN_SETUP, dph-netzwerk.de, dph-netzwerk.de)
}
""");
assertThat(firstOfEach(12, domainDnsSetupAssets)).isEqualToIgnoringWhitespace("""
{
4531=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, l-u-g.org|DNS, DNS-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4532=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, linuxfanboysngirls.de|DNS, DNS-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4534=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, lug-mars.de|DNS, DNS-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00, {"TTL": 14400, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": false, "auto-NS-RR": true, "auto-SOA": false, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ "lug-mars.de. 14400 IN SOA dns1.hostsharing.net. hostmaster.hostsharing.net. 1611590905 10800 3600 604800 3600", "lug-mars.de. 14400 IN MX 10 mailin1.hostsharing.net.", "lug-mars.de. 14400 IN MX 20 mailin2.hostsharing.net.", "lug-mars.de. 14400 IN MX 30 mailin3.hostsharing.net.", "bbb.lug-mars.de. 14400 IN A 83.223.79.72", "ftp.lug-mars.de. 14400 IN A 83.223.79.72", "www.lug-mars.de. 14400 IN A 83.223.79.72" ]}),
4581=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, 1981.ist-im-netz.de|DNS, DNS-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4587=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, mellis.de|DNS, DNS-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": true, "auto-AUTOCONFIG-RR": true, "auto-AUTODISCOVER-RR": true, "auto-DKIM-RR": true, "auto-MAILSERVICES-RR": true, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": true, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": true, "user-RR": [ "dump.hoennig.de. 21600 IN CNAME mih12.hostsharing.net.", "fotos.hoennig.de. 21600 IN CNAME mih12.hostsharing.net.", "maven.hoennig.de. 21600 IN NS dns1.hostsharing.net." ]}),
4589=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, ist-im-netz.de|DNS, DNS-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00, {"TTL": 700, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4600=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, waera.de|DNS, DNS-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": false, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": false, "auto-NS-RR": false, "auto-SOA": false, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": false, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4604=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, xn--wra-qla.de|DNS, DNS-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": false, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": false, "auto-NS-RR": false, "auto-SOA": false, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": false, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
7662=HsHostingAssetRealEntity(DOMAIN_DNS_SETUP, dph-netzwerk.de|DNS, DNS-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": true, "auto-AUTOCONFIG-RR": true, "auto-AUTODISCOVER-RR": true, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": true, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": true, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ "dph-netzwerk.de. 21600 IN TXT \\"v=spf1 include:spf.hostsharing.net ?all\\"", "*.dph-netzwerk.de. 21600 IN TXT \\"v=spf1 include:spf.hostsharing.net ?all\\"" ]})
4531=HsHostingAsset(DOMAIN_DNS_SETUP, l-u-g.org|DNS, DNS-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4532=HsHostingAsset(DOMAIN_DNS_SETUP, linuxfanboysngirls.de|DNS, DNS-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4534=HsHostingAsset(DOMAIN_DNS_SETUP, lug-mars.de|DNS, DNS-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00, {"TTL": 14400, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": false, "auto-NS-RR": true, "auto-SOA": false, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ "lug-mars.de. 14400 IN SOA dns1.hostsharing.net. hostmaster.hostsharing.net. 1611590905 10800 3600 604800 3600", "lug-mars.de. 14400 IN MX 10 mailin1.hostsharing.net.", "lug-mars.de. 14400 IN MX 20 mailin2.hostsharing.net.", "lug-mars.de. 14400 IN MX 30 mailin3.hostsharing.net.", "bbb.lug-mars.de. 14400 IN A 83.223.79.72", "ftp.lug-mars.de. 14400 IN A 83.223.79.72", "www.lug-mars.de. 14400 IN A 83.223.79.72" ]}),
4581=HsHostingAsset(DOMAIN_DNS_SETUP, 1981.ist-im-netz.de|DNS, DNS-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4587=HsHostingAsset(DOMAIN_DNS_SETUP, mellis.de|DNS, DNS-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": true, "auto-AUTOCONFIG-RR": true, "auto-AUTODISCOVER-RR": true, "auto-DKIM-RR": true, "auto-MAILSERVICES-RR": true, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": true, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": true, "user-RR": [ "dump.hoennig.de. 21600 IN CNAME mih12.hostsharing.net.", "fotos.hoennig.de. 21600 IN CNAME mih12.hostsharing.net.", "maven.hoennig.de. 21600 IN NS dns1.hostsharing.net." ]}),
4589=HsHostingAsset(DOMAIN_DNS_SETUP, ist-im-netz.de|DNS, DNS-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00, {"TTL": 700, "auto-A-RR": true, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4600=HsHostingAsset(DOMAIN_DNS_SETUP, waera.de|DNS, DNS-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": false, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": false, "auto-NS-RR": false, "auto-SOA": false, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": false, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
4604=HsHostingAsset(DOMAIN_DNS_SETUP, xn--wra-qla.de|DNS, DNS-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00, {"TTL": 21600, "auto-A-RR": false, "auto-AAAA-RR": false, "auto-AUTOCONFIG-RR": false, "auto-AUTODISCOVER-RR": false, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": false, "auto-MX-RR": false, "auto-NS-RR": false, "auto-SOA": false, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": false, "auto-WILDCARD-AAAA-RR": false, "auto-WILDCARD-MX-RR": false, "auto-WILDCARD-SPF-RR": false, "user-RR": [ ]}),
7662=HsHostingAsset(DOMAIN_DNS_SETUP, dph-netzwerk.de|DNS, DNS-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00, {"TTL": 21600, "auto-A-RR": true, "auto-AAAA-RR": true, "auto-AUTOCONFIG-RR": true, "auto-AUTODISCOVER-RR": true, "auto-DKIM-RR": false, "auto-MAILSERVICES-RR": true, "auto-MX-RR": true, "auto-NS-RR": true, "auto-SOA": true, "auto-SPF-RR": false, "auto-WILDCARD-A-RR": true, "auto-WILDCARD-AAAA-RR": true, "auto-WILDCARD-MX-RR": true, "auto-WILDCARD-SPF-RR": false, "user-RR": [ "dph-netzwerk.de. 21600 IN TXT \\"v=spf1 include:spf.hostsharing.net ?all\\"", "*.dph-netzwerk.de. 21600 IN TXT \\"v=spf1 include:spf.hostsharing.net ?all\\"" ]})
}
""");
assertThat(firstOfEach(12, domainHttpSetupAssets)).isEqualToIgnoringWhitespace("""
{
4531=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, l-u-g.org|HTTP, HTTP-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, UNIX_USER:lug00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4532=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, linuxfanboysngirls.de|HTTP, HTTP-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, UNIX_USER:lug00-wla.2, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4534=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, lug-mars.de|HTTP, HTTP-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, UNIX_USER:lug00-wla.2, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "www" ]}),
4581=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, 1981.ist-im-netz.de|HTTP, HTTP-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4587=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, mellis.de|HTTP, HTTP-Setup für mellis.de, DOMAIN_SETUP:mellis.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": false, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "www", "michael", "test", "photos", "static", "input" ]}),
4589=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, ist-im-netz.de|HTTP, HTTP-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": false, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4600=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, waera.de|HTTP, HTTP-Setup für waera.de, DOMAIN_SETUP:waera.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4604=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, xn--wra-qla.de|HTTP, HTTP-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
7662=HsHostingAssetRealEntity(DOMAIN_HTTP_SETUP, dph-netzwerk.de|HTTP, HTTP-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, UNIX_USER:dph00-dph, {"autoconfig": true, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]})
4531=HsHostingAsset(DOMAIN_HTTP_SETUP, l-u-g.org|HTTP, HTTP-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, UNIX_USER:lug00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4532=HsHostingAsset(DOMAIN_HTTP_SETUP, linuxfanboysngirls.de|HTTP, HTTP-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, UNIX_USER:lug00-wla.2, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4534=HsHostingAsset(DOMAIN_HTTP_SETUP, lug-mars.de|HTTP, HTTP-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, UNIX_USER:lug00-wla.2, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "www" ]}),
4581=HsHostingAsset(DOMAIN_HTTP_SETUP, 1981.ist-im-netz.de|HTTP, HTTP-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4587=HsHostingAsset(DOMAIN_HTTP_SETUP, mellis.de|HTTP, HTTP-Setup für mellis.de, DOMAIN_SETUP:mellis.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": false, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "www", "michael", "test", "photos", "static", "input" ]}),
4589=HsHostingAsset(DOMAIN_HTTP_SETUP, ist-im-netz.de|HTTP, HTTP-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": false, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4600=HsHostingAsset(DOMAIN_HTTP_SETUP, waera.de|HTTP, HTTP-Setup für waera.de, DOMAIN_SETUP:waera.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
4604=HsHostingAsset(DOMAIN_HTTP_SETUP, xn--wra-qla.de|HTTP, HTTP-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, UNIX_USER:mim00, {"autoconfig": false, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": false, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]}),
7662=HsHostingAsset(DOMAIN_HTTP_SETUP, dph-netzwerk.de|HTTP, HTTP-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, UNIX_USER:dph00-dph, {"autoconfig": true, "cgi": true, "fastcgi": true, "fcgi-php-bin": "/usr/lib/cgi-bin/php", "greylisting": true, "htdocsfallback": true, "includes": true, "indexes": true, "letsencrypt": true, "multiviews": true, "passenger": true, "passenger-errorpage": false, "passenger-nodejs": "/usr/bin/node", "passenger-python": "/usr/bin/python3", "passenger-ruby": "/usr/bin/ruby", "subdomains": [ "*" ]})
}
""");
assertThat(firstOfEach(12, domainMBoxSetupAssets)).isEqualToIgnoringWhitespace("""
{
4531=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, l-u-g.org|MBOX, E-Mail-Empfang-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00),
4532=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, linuxfanboysngirls.de|MBOX, E-Mail-Empfang-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00),
4534=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, lug-mars.de|MBOX, E-Mail-Empfang-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00),
4581=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, 1981.ist-im-netz.de|MBOX, E-Mail-Empfang-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4587=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, mellis.de|MBOX, E-Mail-Empfang-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00),
4589=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, ist-im-netz.de|MBOX, E-Mail-Empfang-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4600=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, waera.de|MBOX, E-Mail-Empfang-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00),
4604=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, xn--wra-qla.de|MBOX, E-Mail-Empfang-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00),
7662=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, dph-netzwerk.de|MBOX, E-Mail-Empfang-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00)
4531=HsHostingAsset(DOMAIN_MBOX_SETUP, l-u-g.org|MBOX, E-Mail-Empfang-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00),
4532=HsHostingAsset(DOMAIN_MBOX_SETUP, linuxfanboysngirls.de|MBOX, E-Mail-Empfang-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00),
4534=HsHostingAsset(DOMAIN_MBOX_SETUP, lug-mars.de|MBOX, E-Mail-Empfang-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00),
4581=HsHostingAsset(DOMAIN_MBOX_SETUP, 1981.ist-im-netz.de|MBOX, E-Mail-Empfang-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4587=HsHostingAsset(DOMAIN_MBOX_SETUP, mellis.de|MBOX, E-Mail-Empfang-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00),
4589=HsHostingAsset(DOMAIN_MBOX_SETUP, ist-im-netz.de|MBOX, E-Mail-Empfang-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4600=HsHostingAsset(DOMAIN_MBOX_SETUP, waera.de|MBOX, E-Mail-Empfang-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00),
4604=HsHostingAsset(DOMAIN_MBOX_SETUP, xn--wra-qla.de|MBOX, E-Mail-Empfang-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00),
7662=HsHostingAsset(DOMAIN_MBOX_SETUP, dph-netzwerk.de|MBOX, E-Mail-Empfang-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00)
}
""");
assertThat(firstOfEach(12, domainSmtpSetupAssets)).isEqualToIgnoringWhitespace("""
{
4531=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, l-u-g.org|SMTP, E-Mail-Versand-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00),
4532=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, linuxfanboysngirls.de|SMTP, E-Mail-Versand-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00),
4534=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, lug-mars.de|SMTP, E-Mail-Versand-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00),
4581=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, 1981.ist-im-netz.de|SMTP, E-Mail-Versand-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4587=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, mellis.de|SMTP, E-Mail-Versand-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00),
4589=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, ist-im-netz.de|SMTP, E-Mail-Versand-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4600=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, waera.de|SMTP, E-Mail-Versand-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00),
4604=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, xn--wra-qla.de|SMTP, E-Mail-Versand-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00),
7662=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, dph-netzwerk.de|SMTP, E-Mail-Versand-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00)
4531=HsHostingAsset(DOMAIN_SMTP_SETUP, l-u-g.org|SMTP, E-Mail-Versand-Setup für l-u-g.org, DOMAIN_SETUP:l-u-g.org, MANAGED_WEBSPACE:lug00),
4532=HsHostingAsset(DOMAIN_SMTP_SETUP, linuxfanboysngirls.de|SMTP, E-Mail-Versand-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, MANAGED_WEBSPACE:lug00),
4534=HsHostingAsset(DOMAIN_SMTP_SETUP, lug-mars.de|SMTP, E-Mail-Versand-Setup für lug-mars.de, DOMAIN_SETUP:lug-mars.de, MANAGED_WEBSPACE:lug00),
4581=HsHostingAsset(DOMAIN_SMTP_SETUP, 1981.ist-im-netz.de|SMTP, E-Mail-Versand-Setup für 1981.ist-im-netz.de, DOMAIN_SETUP:1981.ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4587=HsHostingAsset(DOMAIN_SMTP_SETUP, mellis.de|SMTP, E-Mail-Versand-Setup für mellis.de, DOMAIN_SETUP:mellis.de, MANAGED_WEBSPACE:mim00),
4589=HsHostingAsset(DOMAIN_SMTP_SETUP, ist-im-netz.de|SMTP, E-Mail-Versand-Setup für ist-im-netz.de, DOMAIN_SETUP:ist-im-netz.de, MANAGED_WEBSPACE:mim00),
4600=HsHostingAsset(DOMAIN_SMTP_SETUP, waera.de|SMTP, E-Mail-Versand-Setup für waera.de, DOMAIN_SETUP:waera.de, MANAGED_WEBSPACE:mim00),
4604=HsHostingAsset(DOMAIN_SMTP_SETUP, xn--wra-qla.de|SMTP, E-Mail-Versand-Setup für wära.de, DOMAIN_SETUP:xn--wra-qla.de, MANAGED_WEBSPACE:mim00),
7662=HsHostingAsset(DOMAIN_SMTP_SETUP, dph-netzwerk.de|SMTP, E-Mail-Versand-Setup für dph-netzwerk.de, DOMAIN_SETUP:dph-netzwerk.de, MANAGED_WEBSPACE:dph00)
}
""");
}
@ -586,18 +588,18 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(12, emailAddressAssets)).isEqualToIgnoringWhitespace("""
{
54745=HsHostingAssetRealEntity(EMAIL_ADDRESS, lugmaster@l-u-g.org, lugmaster@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "lugmaster", "target": [ "nobody" ]}),
54746=HsHostingAssetRealEntity(EMAIL_ADDRESS, abuse@l-u-g.org, abuse@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "abuse", "target": [ "lug00" ]}),
54747=HsHostingAssetRealEntity(EMAIL_ADDRESS, postmaster@l-u-g.org, postmaster@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "postmaster", "target": [ "nobody" ]}),
54748=HsHostingAssetRealEntity(EMAIL_ADDRESS, webmaster@l-u-g.org, webmaster@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "webmaster", "target": [ "nobody" ]}),
54749=HsHostingAssetRealEntity(EMAIL_ADDRESS, abuse@linuxfanboysngirls.de, abuse@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "abuse", "target": [ "lug00-mars" ]}),
54750=HsHostingAssetRealEntity(EMAIL_ADDRESS, postmaster@linuxfanboysngirls.de, postmaster@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "postmaster", "target": [ "m.hinsel@example.org" ]}),
54751=HsHostingAssetRealEntity(EMAIL_ADDRESS, webmaster@linuxfanboysngirls.de, webmaster@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "webmaster", "target": [ "m.hinsel@example.org" ]}),
54755=HsHostingAssetRealEntity(EMAIL_ADDRESS, abuse@lug-mars.de, abuse@lug-mars.de, DOMAIN_MBOX_SETUP:lug-mars.de|MBOX, {"local-part": "abuse", "target": [ "lug00-marl" ]}),
54756=HsHostingAssetRealEntity(EMAIL_ADDRESS, postmaster@lug-mars.de, postmaster@lug-mars.de, DOMAIN_MBOX_SETUP:lug-mars.de|MBOX, {"local-part": "postmaster", "target": [ "m.hinsel@example.org" ]}),
54757=HsHostingAssetRealEntity(EMAIL_ADDRESS, webmaster@lug-mars.de, webmaster@lug-mars.de, DOMAIN_MBOX_SETUP:lug-mars.de|MBOX, {"local-part": "webmaster", "target": [ "m.hinsel@example.org" ]}),
54760=HsHostingAssetRealEntity(EMAIL_ADDRESS, info@hamburg-west.l-u-g.org, info@hamburg-west.l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "info", "sub-domain": "hamburg-west", "target": [ "peter.lottmann@example.com" ]}),
54761=HsHostingAssetRealEntity(EMAIL_ADDRESS, lugmaster@hamburg-west.l-u-g.org, lugmaster@hamburg-west.l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "lugmaster", "sub-domain": "hamburg-west", "target": [ "raoul.lottmann@example.com" ]})
54745=HsHostingAsset(EMAIL_ADDRESS, lugmaster@l-u-g.org, lugmaster@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "lugmaster", "target": [ "nobody" ]}),
54746=HsHostingAsset(EMAIL_ADDRESS, abuse@l-u-g.org, abuse@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "abuse", "target": [ "lug00" ]}),
54747=HsHostingAsset(EMAIL_ADDRESS, postmaster@l-u-g.org, postmaster@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "postmaster", "target": [ "nobody" ]}),
54748=HsHostingAsset(EMAIL_ADDRESS, webmaster@l-u-g.org, webmaster@l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "webmaster", "target": [ "nobody" ]}),
54749=HsHostingAsset(EMAIL_ADDRESS, abuse@linuxfanboysngirls.de, abuse@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "abuse", "target": [ "lug00-mars" ]}),
54750=HsHostingAsset(EMAIL_ADDRESS, postmaster@linuxfanboysngirls.de, postmaster@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "postmaster", "target": [ "m.hinsel@example.org" ]}),
54751=HsHostingAsset(EMAIL_ADDRESS, webmaster@linuxfanboysngirls.de, webmaster@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "webmaster", "target": [ "m.hinsel@example.org" ]}),
54755=HsHostingAsset(EMAIL_ADDRESS, abuse@lug-mars.de, abuse@lug-mars.de, DOMAIN_MBOX_SETUP:lug-mars.de|MBOX, {"local-part": "abuse", "target": [ "lug00-marl" ]}),
54756=HsHostingAsset(EMAIL_ADDRESS, postmaster@lug-mars.de, postmaster@lug-mars.de, DOMAIN_MBOX_SETUP:lug-mars.de|MBOX, {"local-part": "postmaster", "target": [ "m.hinsel@example.org" ]}),
54757=HsHostingAsset(EMAIL_ADDRESS, webmaster@lug-mars.de, webmaster@lug-mars.de, DOMAIN_MBOX_SETUP:lug-mars.de|MBOX, {"local-part": "webmaster", "target": [ "m.hinsel@example.org" ]}),
54760=HsHostingAsset(EMAIL_ADDRESS, info@hamburg-west.l-u-g.org, info@hamburg-west.l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "info", "sub-domain": "hamburg-west", "target": [ "peter.lottmann@example.com" ]}),
54761=HsHostingAsset(EMAIL_ADDRESS, lugmaster@hamburg-west.l-u-g.org, lugmaster@hamburg-west.l-u-g.org, DOMAIN_MBOX_SETUP:l-u-g.org|MBOX, {"local-part": "lugmaster", "sub-domain": "hamburg-west", "target": [ "raoul.lottmann@example.com" ]})
}
""");
}
@ -609,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());
}
@ -877,21 +879,21 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(15, unixUserAssets)).isEqualToIgnoringWhitespace("""
{
5803=HsHostingAssetRealEntity(UNIX_USER, lug00, LUGs, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102090}),
5805=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.1, Paul Klemm, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102091}),
5809=HsHostingAssetRealEntity(UNIX_USER, lug00-wla.2, Walter Müller, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 8, "SSD soft quota": 4, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102093}),
5811=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.a, LUG OLA - POP a, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/usr/bin/passwd", "userid": 102094}),
5813=HsHostingAssetRealEntity(UNIX_USER, lug00-ola.b, LUG OLA - POP b, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/usr/bin/passwd", "userid": 102095}),
5835=HsHostingAssetRealEntity(UNIX_USER, lug00-test, Test, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 1024, "SSD soft quota": 1024, "locked": false, "password": null, "shell": "/usr/bin/passwd", "userid": 102106}),
5961=HsHostingAssetRealEntity(UNIX_USER, xyz68, Monitoring h68, MANAGED_WEBSPACE:xyz68, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102141}),
5964=HsHostingAssetRealEntity(UNIX_USER, mim00, Michael Mellis, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102147}),
5966=HsHostingAssetRealEntity(UNIX_USER, mim00-1981, Jahrgangstreffen 1981, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 256, "SSD soft quota": 128, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102148}),
5990=HsHostingAssetRealEntity(UNIX_USER, mim00-mail, Mailbox, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102160}),
6705=HsHostingAssetRealEntity(UNIX_USER, hsh00-mim, Michael Mellis, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/false", "userid": 10003}),
6824=HsHostingAssetRealEntity(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 10000}),
7846=HsHostingAssetRealEntity(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/false", "userid": 110568}),
9546=HsHostingAssetRealEntity(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110593}),
9596=HsHostingAssetRealEntity(UNIX_USER, dph00-dph, Domain admin, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110594})
5803=HsHostingAsset(UNIX_USER, lug00, LUGs, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102090}),
5805=HsHostingAsset(UNIX_USER, lug00-wla.1, Paul Klemm, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102091}),
5809=HsHostingAsset(UNIX_USER, lug00-wla.2, Walter Müller, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 8, "SSD soft quota": 4, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102093}),
5811=HsHostingAsset(UNIX_USER, lug00-ola.a, LUG OLA - POP a, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/usr/bin/passwd", "userid": 102094}),
5813=HsHostingAsset(UNIX_USER, lug00-ola.b, LUG OLA - POP b, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/usr/bin/passwd", "userid": 102095}),
5835=HsHostingAsset(UNIX_USER, lug00-test, Test, MANAGED_WEBSPACE:lug00, {"SSD hard quota": 1024, "SSD soft quota": 1024, "locked": false, "password": null, "shell": "/usr/bin/passwd", "userid": 102106}),
5961=HsHostingAsset(UNIX_USER, xyz68, Monitoring h68, MANAGED_WEBSPACE:xyz68, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102141}),
5964=HsHostingAsset(UNIX_USER, mim00, Michael Mellis, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102147}),
5966=HsHostingAsset(UNIX_USER, mim00-1981, Jahrgangstreffen 1981, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 256, "SSD soft quota": 128, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102148}),
5990=HsHostingAsset(UNIX_USER, mim00-mail, Mailbox, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 102160}),
6705=HsHostingAsset(UNIX_USER, hsh00-mim, Michael Mellis, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/false", "userid": 10003}),
6824=HsHostingAsset(UNIX_USER, hsh00, Hostsharing Paket, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 10000}),
7846=HsHostingAsset(UNIX_USER, hsh00-dph, hsh00-uph, MANAGED_WEBSPACE:hsh00, {"HDD hard quota": 0, "HDD soft quota": 0, "SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/false", "userid": 110568}),
9546=HsHostingAsset(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110593}),
9596=HsHostingAsset(UNIX_USER, dph00-dph, Domain admin, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "password": null, "shell": "/bin/bash", "userid": 110594})
}
""");
}
@ -958,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) {
@ -1064,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))
@ -1117,7 +1119,7 @@ public class ImportHostingAssets extends ImportOfficeData {
&& managedWebspace.getRelatedProject().getDebitor().getDebitorNumber() == 10000_00 ) {
assertThat(managedWebspace.getIdentifier()).startsWith("xyz");
final var hshDebitor = managedWebspace.getBookingItem().getProject().getDebitor();
final var newProject = HsBookingProjectEntity.builder()
final var newProject = HsBookingProjectRealEntity.builder()
.debitor(hshDebitor)
.caption(parentAsset.getIdentifier() + " Monitor")
.build();

View File

@ -140,7 +140,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
});
// then
result.assertExceptionWithRootCauseMessage(org.hibernate.exception.ConstraintViolationException.class);
result.assertExceptionWithRootCauseMessage(org.hibernate.exception.ConstraintViolationException.class,
"ERROR: new row for relation \"hs_office_debitor\" violates check constraint \"check_default_prefix\"");
}
@Test

View File

@ -161,7 +161,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
.extract().header("Location"); // @formatter:on
// finally, the new relation can be accessed under the generated UUID
final var newUserUuid = toCleanup(HsOfficeRelation.class, UUID.fromString(
final var newUserUuid = toCleanup(HsOfficeRelationRealEntity.class, UUID.fromString(
location.substring(location.lastIndexOf('/') + 1)));
assertThat(newUserUuid).isNotNull();
}

View File

@ -7,6 +7,7 @@ import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import org.apache.commons.collections4.SetUtils;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@ -20,6 +21,7 @@ import jakarta.persistence.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
import java.util.regex.Pattern;
import static java.lang.System.out;
import static java.util.Comparator.comparing;
@ -55,9 +57,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
private static Long latestIntialTestDataSerialId;
private static boolean countersInitialized = false;
private static boolean initialTestDataValidated = false;
private static Long initialRbacObjectCount = null;
private static Long initialRbacRoleCount = null;
private static Long initialRbacGrantCount = null;
static private Long previousRbacObjectCount;
private Long initialRbacObjectCount = null;
private Long initialRbacRoleCount = null;
private Long initialRbacGrantCount = null;
private Set<String> initialRbacObjects;
private Set<String> initialRbacRoles;
private Set<String> initialRbacGrants;
@ -119,6 +122,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
@BeforeEach
//@Transactional -- TODO: check why this does not work but jpaAttempt.transacted does work
void retrieveInitialTestData(final TestInfo testInfo) {
this.testInfo = testInfo;
out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".retrieveInitialTestData");
if (latestIntialTestDataSerialId == null ) {
@ -126,7 +130,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
}
if (initialRbacObjects != null){
assertNoNewRbacObjectsRolesAndGrantsLeaked();
assertNoNewRbacObjectsRolesAndGrantsLeaked("before");
}
initialTestDataValidated = false;
@ -156,7 +160,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
assertThat(countersInitialized).as("error while retrieving initial test data").isTrue();
assertThat(initialTestDataValidated).as("check previous test for leaked test data").isTrue();
out.println("TOTAL OBJECT COUNT (before): " + initialRbacObjectCount);
out.println(testInfo.getDisplayName() + ": TOTAL OBJECT COUNT (initial): " + previousRbacObjectCount + " -> " + initialRbacObjectCount);
if (previousRbacObjectCount != null) {
assertThat(initialRbacObjectCount).as("TOTAL OBJECT COUNT changed from " + previousRbacObjectCount + " to " + initialRbacObjectCount).isEqualTo(previousRbacObjectCount);
}
}
private Long assumeSameInitialCount(final Long countBefore, final long currentCount, final String name) {
@ -166,23 +173,15 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
return currentCount;
}
@BeforeEach
void keepTestInfo(final TestInfo testInfo) {
this.testInfo = testInfo;
}
@AfterEach
void cleanupAndCheckCleanup(final TestInfo testInfo) {
// If the whole test method has its own transaction, cleanup makes no sense.
// If that transaction even failed, cleaunup would cause an exception.
if (!tm.getTransaction(null).isRollbackOnly()) {
this.testInfo = testInfo;
out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".cleanupAndCheckCleanup");
cleanupTemporaryTestData();
repeatUntilTrue(3, this::deleteLeakedRbacObjects);
long rbacObjectCount = assertNoNewRbacObjectsRolesAndGrantsLeaked();
out.println("TOTAL OBJECT COUNT (after): " + rbacObjectCount);
}
assertNoNewRbacObjectsRolesAndGrantsLeaked("after");
}
private void cleanupTemporaryTestData() {
@ -207,8 +206,8 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
}
}
private long assertNoNewRbacObjectsRolesAndGrantsLeaked() {
return jpaAttempt.transacted(() -> {
private void assertNoNewRbacObjectsRolesAndGrantsLeaked(final String event) {
long rbacObjectCount = jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net");
assertEqual(initialRbacObjects, allRbacObjects());
if (DETAILED_BUT_SLOW_CHECK) {
@ -218,21 +217,27 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
// The detailed check works with sets, thus it cannot determine duplicates.
// Therefore, we always compare the counts as well.
long rbacObjectCount = 0;
assertThat(rbacObjectCount = rbacObjectRepo.count()).as("not all business objects got cleaned up (by current test)")
long count = rbacObjectRepo.count();
out.println(testInfo.getDisplayName() + ": TOTAL OBJECT COUNT (" + event+ "): " + previousRbacObjectCount+ " -> " + count);
assertThat(count).as("not all business objects got cleaned up (by current test)")
.isEqualTo(initialRbacObjectCount);
assertThat(rbacRoleRepo.count()).as("not all rbac roles got cleaned up (by current test)")
.isEqualTo(initialRbacRoleCount);
assertThat(rbacGrantRepo.count()).as("not all rbac grants got cleaned up (by current test)")
.isEqualTo(initialRbacGrantCount);
return rbacObjectCount;
return count;
}).assertSuccessful().returnedValue();
if (previousRbacObjectCount != null) {
assertThat(rbacObjectCount).as("TOTAL OBJECT COUNT changed from " + previousRbacObjectCount + " to " + rbacObjectCount).isEqualTo(previousRbacObjectCount);
}
previousRbacObjectCount = rbacObjectCount;
}
private boolean deleteLeakedRbacObjects() {
final var deletionSuccessful = new AtomicBoolean(true);
rbacObjectRepo.findAll().stream()
.filter(o -> o.serialId > latestIntialTestDataSerialId)
jpaAttempt.transacted(() -> rbacObjectRepo.findAll()).assertSuccessful().returnedValue().stream()
.filter(o -> latestIntialTestDataSerialId != null && o.serialId > latestIntialTestDataSerialId)
.sorted(comparing(o -> o.serialId))
.forEach(o -> {
final var exception = jpaAttempt.transacted(() -> {
@ -256,7 +261,8 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
private void assertEqual(final Set<String> before, final Set<String> after) {
assertThat(before).isNotNull();
assertThat(after).isNotNull();
assertThat(difference(before, after)).as("missing entities (deleted initial test data)").isEmpty();
final SetUtils.SetView<String> difference = difference(before, after);
assertThat(difference).as("missing entities (deleted initial test data)").isEmpty();
assertThat(difference(after, before)).as("spurious entities (test data not cleaned up by this test)").isEmpty();
}
@ -291,8 +297,28 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
}
/**
* Generates a diagram of the RBAC-Grants to the current subjects (user or assumed roles).
* @return an array of all RBAC roles matching the given pattern
*
* Usually unused, but for temporary debugging purposes of findind role names for new tests.
*/
@SuppressWarnings("unused")
protected String[] roleNames(final String sqlLikeExpression) {
final var pattern = Pattern.compile(sqlLikeExpression);
//noinspection unchecked
final List<Object[]> rows = (List<Object[]>) em.createNativeQuery("select * from rbacrole_ev where roleidname like 'hs_booking_project#%'")
.getResultList();
return rows.stream()
.map(row -> (row[0]).toString())
.filter(roleName -> pattern.matcher(roleName).matches())
.toArray(String[]::new);
}
/**
* Generates a diagram of the RBAC-Grants to the current subjects (user or assumed roles).
*
* Usually unused, but for temporary use for debugging and other analysis.
*/
@SuppressWarnings("unused")
protected void generateRbacDiagramForCurrentSubjects(final EnumSet<RbacGrantsDiagramService.Include> include, final String name) {
RbacGrantsDiagramService.writeToFile(
name,
@ -303,7 +329,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
/**
* Generates a diagram of the RBAC-Grants for the given object and permission.
*
* Usually unused, but for temporary use for debugging and other analysis.
*/
@SuppressWarnings("unused")
protected void generateRbacDiagramForObjectPermission(final UUID targetObject, final String rbacOp, final String name) {
RbacGrantsDiagramService.writeToFile(
name,

View File

@ -77,11 +77,11 @@ public class JpaAttempt {
public static class JpaResult<T> {
private final T result;
private final T value;
private final RuntimeException exception;
private JpaResult(final T result, final RuntimeException exception) {
this.result = result;
private JpaResult(final T value, final RuntimeException exception) {
this.value = value;
this.exception = exception;
}
@ -102,7 +102,7 @@ public class JpaAttempt {
}
public T returnedValue() {
return result;
return value;
}
public ObjectAssert<T> assertThatResult() {

View File

@ -66,7 +66,8 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
// then
result.assertExceptionWithRootCauseMessage(
PersistenceException.class,
"ERROR: [403] insert into test_customer not allowed for current subjects {test_customer#xxx:ADMIN}");
"ERROR: [403] insert into test_customer ",
"not allowed for current subjects {test_customer#xxx:ADMIN}");
}
@Test
@ -84,7 +85,8 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
// then
result.assertExceptionWithRootCauseMessage(
PersistenceException.class,
"ERROR: [403] insert into test_customer not allowed for current subjects {customer-admin@xxx.example.com}");
"ERROR: [403] insert into test_customer ",
" not allowed for current subjects {customer-admin@xxx.example.com}");
}