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; private Mapper mapper;
@Autowired @Autowired
private HsBookingItemRepository bookingItemRepo; private HsBookingItemRbacRepository bookingItemRepo;
@PersistenceContext @PersistenceContext
private EntityManager em; private EntityManager em;
@ -61,9 +61,9 @@ public class HsBookingItemController implements HsBookingItemsApi {
context.define(currentUser, assumedRoles); 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 = final var uri =
MvcUriComponentsBuilder.fromController(getClass()) MvcUriComponentsBuilder.fromController(getClass())
@ -119,19 +119,19 @@ public class HsBookingItemController implements HsBookingItemsApi {
new HsBookingItemEntityPatcher(current).apply(body); 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); final var mapped = mapper.map(saved, HsBookingItemResource.class, ENTITY_TO_RESOURCE_POSTMAPPER);
return ResponseEntity.ok(mapped); 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()); resource.setValidFrom(entity.getValidity().lower());
if (entity.getValidity().hasUpperBound()) { if (entity.getValidity().hasUpperBound()) {
resource.setValidTo(entity.getValidity().upper().minusDays(1)); 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.setValidity(toPostgresDateRange(LocalDate.now(), resource.getValidTo()));
entity.putResources(KeyValueMap.from(resource.getResources())); 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> { 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; 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; package net.hostsharing.hsadminng.hs.booking.item;
import org.springframework.data.repository.Repository;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; 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); int deleteByUuid(final UUID uuid);

View File

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

View File

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

View File

@ -1,13 +1,15 @@
package net.hostsharing.hsadminng.hs.booking.item.validators; 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 net.hostsharing.hsadminng.hs.validation.IntegerProperty;
import org.apache.commons.lang3.function.TriFunction; import org.apache.commons.lang3.function.TriFunction;
import java.util.List; import java.util.List;
import java.util.Optional;
import static java.util.Collections.emptyList; 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.DOMAIN_MBOX_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ADDRESS; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.EMAIL_ADDRESS;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MARIADB_DATABASE; 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() { private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> unixUsers() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> { return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset()) final var unixUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream() .map(ha -> ha.getSubHostingAssets().stream()
.filter(subAsset -> subAsset.getType() == UNIX_USER) .filter(subAsset -> subAsset.getType() == UNIX_USER)
.count()) .count())
@ -53,9 +55,9 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
}; };
} }
private static TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> databaseUsers() { private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> databaseUsers() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> { return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var dbUserCount = ofNullable(entity.getRelatedHostingAsset()) final var dbUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream() .map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType() == PGSQL_USER || bi.getType() == MARIADB_USER ) .filter(bi -> bi.getType() == PGSQL_USER || bi.getType() == MARIADB_USER )
.count()) .count())
@ -68,9 +70,9 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
}; };
} }
private static TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> databases() { private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> databases() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> { return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset()) final var unixUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream() .map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType()==PGSQL_USER || bi.getType()==MARIADB_USER ) .filter(bi -> bi.getType()==PGSQL_USER || bi.getType()==MARIADB_USER )
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream() .flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
@ -85,9 +87,9 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
}; };
} }
private static TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> eMailAddresses() { private static TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> eMailAddresses() {
return (final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> { return (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var unixUserCount = ofNullable(entity.getRelatedHostingAsset()) final var unixUserCount = fetchRelatedBookingItem(entity)
.map(ha -> ha.getSubHostingAssets().stream() .map(ha -> ha.getSubHostingAssets().stream()
.filter(bi -> bi.getType() == DOMAIN_MBOX_SETUP) .filter(bi -> bi.getType() == DOMAIN_MBOX_SETUP)
.flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream() .flatMap(domainEMailSetup -> domainEMailSetup.getSubHostingAssets().stream()
@ -101,4 +103,13 @@ class HsManagedWebspaceBookingItemValidator extends HsBookingItemEntityValidator
return emptyList(); 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; package net.hostsharing.hsadminng.hs.booking.project;
import lombok.*; import lombok.*;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity; import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity; import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity; 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.rbac.rbacdef.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Builder @MappedSuperclass
@Entity
@Table(name = "hs_booking_project_rv")
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor @AllArgsConstructor(access = AccessLevel.PROTECTED)
public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBookingProjectEntity> { @SuperBuilder(builderMethodName = "baseBuilder", toBuilder = true)
public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBookingProject> {
private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class) private static Stringify<HsBookingProject> stringify = stringify(HsBookingProject.class)
.withProp(HsBookingProjectEntity::getDebitor) .withProp(HsBookingProject::getDebitor)
.withProp(HsBookingProjectEntity::getCaption) .withProp(HsBookingProject::getCaption)
.quotedValues(false); .quotedValues(false);
@Id @Id
@ -67,7 +67,7 @@ public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBooki
} }
public static RbacView rbac() { public static RbacView rbac() {
return rbacViewFor("project", HsBookingProjectEntity.class) return rbacViewFor("project", HsBookingProject.class)
.withIdentityView(SQL.query(""" .withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject FROM hs_booking_project bookingProject

View File

@ -28,7 +28,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
private Mapper mapper; private Mapper mapper;
@Autowired @Autowired
private HsBookingProjectRepository bookingProjectRepo; private HsBookingProjectRbacRepository bookingProjectRepo;
@Autowired @Autowired
private HsBookingDebitorRepository debitorRepo; private HsBookingDebitorRepository debitorRepo;
@ -56,7 +56,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
context.define(currentUser, assumedRoles); 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); final var saved = bookingProjectRepo.save(entityToSave);
@ -118,7 +118,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
return ResponseEntity.ok(mapped); 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) { if (resource.getDebitorUuid() != null) {
entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid()) entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid())
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] debitorUuid %s not found".formatted( .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> { 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; 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; package net.hostsharing.hsadminng.hs.booking.project;
import org.springframework.data.repository.Repository;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public interface HsBookingProjectRepository extends Repository<HsBookingProjectEntity, UUID> { public interface HsBookingProjectRepository<E extends HsBookingProject> {
Optional<HsBookingProjectEntity> findByUuid(final UUID bookingProjectUuid); Optional<E> findByUuid(final UUID bookingProjectUuid);
List<HsBookingProjectEntity> findByCaption(final String projectCaption); 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); int deleteByUuid(final UUID uuid);

View File

@ -1,13 +1,40 @@
package net.hostsharing.hsadminng.hs.hosting.asset; package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import io.hypersistence.utils.hibernate.type.json.JsonType;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity; 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.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider; import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity; import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import net.hostsharing.hsadminng.stringify.Stringify; import net.hostsharing.hsadminng.stringify.Stringify;
import net.hostsharing.hsadminng.stringify.Stringifyable; 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.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@ -16,9 +43,15 @@ import java.util.UUID;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify; 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::getType)
.withProp(HsHostingAsset::getIdentifier) .withProp(HsHostingAsset::getIdentifier)
.withProp(HsHostingAsset::getCaption) .withProp(HsHostingAsset::getCaption)
@ -28,29 +61,83 @@ public interface HsHostingAsset extends Stringifyable, BaseEntity<HsHostingAsset
.withProp(HsHostingAsset::getConfig) .withProp(HsHostingAsset::getConfig)
.quotedValues(false); .quotedValues(false);
@Id
@GeneratedValue
private UUID uuid;
void setUuid(UUID uuid); @Version
HsHostingAssetType getType(); private int version;
HsHostingAsset getParentAsset();
void setIdentifier(String s);
String getIdentifier();
HsBookingItemEntity getBookingItem();
HsHostingAsset getAssignedToAsset();
HsOfficeContactRealEntity getAlarmContact();
List<? extends HsHostingAsset> getSubHostingAssets();
String getCaption();
Map<String, Object> getConfig();
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()) return Optional.ofNullable(getBookingItem())
.map(HsBookingItemEntity::getRelatedProject) .map(HsBookingItem::getRelatedProject)
.orElseGet(() -> Optional.ofNullable(getParentAsset()) .orElseGet(() -> Optional.ofNullable(getParentAsset())
.map(HsHostingAsset::getRelatedProject) .map(HsHostingAsset::getRelatedProject)
.orElse(null)); .orElse(null));
} }
@Override @Override
default Object getContextValue(final String propName) { public Object getContextValue(final String propName) {
final var v = directProps().get(propName); final var v = directProps().get(propName);
if (v != null) { if (v != null) {
return v; return v;
@ -66,7 +153,12 @@ public interface HsHostingAsset extends Stringifyable, BaseEntity<HsHostingAsset
} }
@Override @Override
default String toShortString() { public String toShortString() {
return getType() + ":" + getIdentifier(); return getType() + ":" + getIdentifier();
} }
@Override
public String toString() {
return stringify.apply(this);
}
} }

View File

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

View File

@ -12,9 +12,9 @@ import java.util.Optional;
public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAssetPatchResource> { public class HsHostingAssetEntityPatcher implements EntityPatcher<HsHostingAssetPatchResource> {
private final EntityManager em; 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.em = em;
this.entity = entity; this.entity = entity;
} }

View File

@ -1,41 +1,17 @@
package net.hostsharing.hsadminng.hs.hosting.asset; 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.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity; 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;
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL; 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.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.Table;
import jakarta.persistence.Transient;
import jakarta.persistence.Version;
import java.io.IOException; 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.CaseDef.inCaseOf;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn; 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.SQL.directlyFetchedByDependsOnColumn;
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor; import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
@Builder
@Entity @Entity
@Table(name = "hs_hosting_asset_rv") @Table(name = "hs_hosting_asset_rv")
@SuperBuilder(toBuilder = true)
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor public class HsHostingAssetRbacEntity extends HsHostingAsset {
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 static RbacView rbac() { public static RbacView rbac() {
return rbacViewFor("asset", HsHostingAssetEntity.class) return rbacViewFor("asset", HsHostingAssetRbacEntity.class)
.withIdentityView(SQL.projection("identifier")) .withIdentityView(SQL.projection("identifier"))
.withRestrictedViewOrderBy(SQL.expression("identifier")) .withRestrictedViewOrderBy(SQL.expression("identifier"))
.withUpdatableColumns("version", "caption", "config", "assignedToAssetUuid", "alarmContactUuid") .withUpdatableColumns("version", "caption", "config", "assignedToAssetUuid", "alarmContactUuid")
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data? .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"), dependsOnColumn("bookingItemUuid"),
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),
NULLABLE) NULLABLE)
.importEntityAlias("parentAsset", HsHostingAssetEntity.class, usingDefaultCase(), .importEntityAlias("parentAsset", HsHostingAssetRbacEntity.class, usingDefaultCase(),
dependsOnColumn("parentAssetUuid"), dependsOnColumn("parentAssetUuid"),
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),
NULLABLE) NULLABLE)
.toRole("parentAsset", ADMIN).grantPermission(INSERT) .toRole("parentAsset", ADMIN).grantPermission(INSERT)
.importEntityAlias("assignedToAsset", HsHostingAssetEntity.class, usingDefaultCase(), .importEntityAlias("assignedToAsset", HsHostingAssetRbacEntity.class, usingDefaultCase(),
dependsOnColumn("assignedToAssetUuid"), dependsOnColumn("assignedToAssetUuid"),
directlyFetchedByDependsOnColumn(), directlyFetchedByDependsOnColumn(),
NULLABLE) 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; 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.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; 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 = """ default List<E> findAllByCriteria(final UUID projectUuid, final UUID parentAssetUuid, final HsHostingAssetType type) {
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) {
return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type)); return findAllByCriteriaImpl(projectUuid, parentAssetUuid, HsHostingAssetType.asString(type));
} }
HsHostingAssetEntity save(HsHostingAsset current); E save(HsHostingAsset current);
int deleteByUuid(final UUID uuid); int deleteByUuid(final UUID uuid);

View File

@ -1,7 +1,7 @@
package net.hostsharing.hsadminng.hs.hosting.asset; package net.hostsharing.hsadminng.hs.hosting.asset;
import lombok.AllArgsConstructor; 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.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.item.Node; import net.hostsharing.hsadminng.hs.booking.item.Node;
@ -354,14 +354,14 @@ class EntityTypeRelation<E, T extends Node> {
final HsHostingAssetType.RelationPolicy relationPolicy; final HsHostingAssetType.RelationPolicy relationPolicy;
final HsHostingAssetType.RelationType relationType; final HsHostingAssetType.RelationType relationType;
final Function<HsHostingAssetEntity, E> getter; final Function<HsHostingAssetRbacEntity, E> getter;
private final List<T> acceptedRelatedTypes; private final List<T> acceptedRelatedTypes;
final String edge; final String edge;
private EntityTypeRelation( private EntityTypeRelation(
final HsHostingAssetType.RelationPolicy relationPolicy, final HsHostingAssetType.RelationPolicy relationPolicy,
final HsHostingAssetType.RelationType relationType, final HsHostingAssetType.RelationType relationType,
final Function<HsHostingAssetEntity, E> getter, final Function<HsHostingAssetRbacEntity, E> getter,
final T acceptedRelatedType, final T acceptedRelatedType,
final String edge final String edge
) { ) {
@ -376,11 +376,11 @@ class EntityTypeRelation<E, T extends Node> {
return (Set<R>) result; return (Set<R>) result;
} }
static EntityTypeRelation<HsBookingItemEntity, HsBookingItemType> requires(final HsBookingItemType bookingItemType) { static EntityTypeRelation<HsBookingItem, HsBookingItemType> requires(final HsBookingItemType bookingItemType) {
return new EntityTypeRelation<>( return new EntityTypeRelation<>(
REQUIRED, REQUIRED,
BOOKING_ITEM, BOOKING_ITEM,
HsHostingAssetEntity::getBookingItem, HsHostingAssetRbacEntity::getBookingItem,
bookingItemType, 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) /// validates the entity within it's parent and child hierarchy (e.g. totals validators and other limits)
public HostingAssetEntitySaveProcessor validateContext() { public HostingAssetEntitySaveProcessor validateContext() {
step("validateContext", "mapUsing"); step("validateContext", "mapUsing");
MultiValidationException.throwIfNotEmpty(validator.validateContext(entity)); return HsEntityValidator.doWithEntityManager(em, () -> {
return this; MultiValidationException.throwIfNotEmpty(validator.validateContext(entity));
return this;
});
} }
/// maps entity to JSON resource representation /// maps entity to JSON resource representation

View File

@ -1,6 +1,6 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators; 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.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry; import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset; 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]; 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> parentAssetReferenceValidation;
private final ReferenceValidator<HsHostingAsset, HsHostingAssetType> assignedToAssetReferenceValidation; private final ReferenceValidator<HsHostingAsset, HsHostingAssetType> assignedToAssetReferenceValidation;
private final HostingAssetEntityValidator.AlarmContact alarmContactValidation; private final HostingAssetEntityValidator.AlarmContact alarmContactValidation;
@ -41,7 +41,7 @@ public abstract class HostingAssetEntityValidator extends HsEntityValidator<HsHo
assetType.bookingItemPolicy(), assetType.bookingItemPolicy(),
assetType.bookingItemTypes(), assetType.bookingItemTypes(),
HsHostingAsset::getBookingItem, HsHostingAsset::getBookingItem,
HsBookingItemEntity::getType); HsBookingItem::getType);
this.parentAssetReferenceValidation = new ReferenceValidator<>( this.parentAssetReferenceValidation = new ReferenceValidator<>(
assetType.parentAssetPolicy(), assetType.parentAssetPolicy(),
assetType.parentAssetTypes(), assetType.parentAssetTypes(),
@ -104,7 +104,7 @@ public abstract class HostingAssetEntityValidator extends HsEntityValidator<HsHo
: emptyList(); : emptyList();
} }
private static List<String> optionallyValidate(final HsBookingItemEntity bookingItem) { private static List<String> optionallyValidate(final HsBookingItem bookingItem) {
return bookingItem != null return bookingItem != null
? enrich( ? enrich(
prefix(bookingItem.toShortString(), "bookingItem"), 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.HsHostingAsset; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType; 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 net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import java.util.*; import java.util.*;
@ -54,13 +53,4 @@ public class HostingAssetEntityValidatorRegistry {
public static Set<Enum<HsHostingAssetType>> types() { public static Set<Enum<HsHostingAssetType>> types() {
return validators.keySet(); 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 // TODO.refa: rename to HsEntityProcessor, also subclasses
public abstract class HsEntityValidator<E extends PropertiesProvider> { public abstract class HsEntityValidator<E extends PropertiesProvider> {
public static final ThreadLocal<EntityManager> localEntityManager = new ThreadLocal<>();
public final ValidatableProperty<?, ?>[] propertyValidators; public final ValidatableProperty<?, ?>[] propertyValidators;
public <T extends Enum <T>> HsEntityValidator(final ValidatableProperty<?, ?>... validators) { public <T extends Enum <T>> HsEntityValidator(final ValidatableProperty<?, ?>... validators) {
@ -39,6 +41,15 @@ public abstract class HsEntityValidator<E extends PropertiesProvider> {
return String.join(".", parts); 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> validateEntity(final E entity);
public abstract List<String> validateContext(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.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.experimental.Accessors; 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 net.hostsharing.hsadminng.mapper.Array;
import org.apache.commons.lang3.function.TriFunction; import org.apache.commons.lang3.function.TriFunction;
@ -73,7 +73,7 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
private boolean isTotalsValidator = false; private boolean isTotalsValidator = false;
@JsonIgnore @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 private Integer thresholdPercentage; // TODO.impl: move to IntegerProperty
@ -151,8 +151,8 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
if (asTotalLimitValidators == null) { if (asTotalLimitValidators == null) {
asTotalLimitValidators = new ArrayList<>(); asTotalLimitValidators = new ArrayList<>();
} }
final TriFunction<HsBookingItemEntity, IntegerProperty<?>, Integer, List<String>> validator = final TriFunction<HsBookingItem, IntegerProperty<?>, Integer, List<String>> validator =
(final HsBookingItemEntity entity, final IntegerProperty<?> prop, final Integer factor) -> { (final HsBookingItem entity, final IntegerProperty<?> prop, final Integer factor) -> {
final var total = entity.getSubBookingItems().stream() final var total = entity.getSubBookingItems().stream()
.map(server -> server.getResources().get(propertyName)) .map(server -> server.getResources().get(propertyName))
@ -167,7 +167,7 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
} }
return emptyList(); 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(); return self();
} }
@ -183,11 +183,11 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
return thresholdPercentage; 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) { if (asTotalLimitValidators == null) {
asTotalLimitValidators = new ArrayList<>(); 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; return this;
} }
@ -323,7 +323,7 @@ public abstract class ValidatableProperty<P extends ValidatableProperty<?, ?>, T
return value; return value;
} }
public List<String> validateTotals(final HsBookingItemEntity bookingItem) { public List<String> validateTotals(final HsBookingItem bookingItem) {
if (asTotalLimitValidators==null) { if (asTotalLimitValidators==null) {
return emptyList(); return emptyList();
} }

View File

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

View File

@ -1,6 +1,9 @@
package net.hostsharing.hsadminng.arch; package net.hostsharing.hsadminng.arch;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.JavaClass; 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.AnalyzeClasses;
import com.tngtech.archunit.junit.ArchTest; import com.tngtech.archunit.junit.ArchTest;
import com.tngtech.archunit.lang.ArchCondition; 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.ConditionEvents;
import com.tngtech.archunit.lang.SimpleConditionEvent; import com.tngtech.archunit.lang.SimpleConditionEvent;
import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRbacEntity;
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest; import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService; import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
import org.springframework.data.repository.Repository; import org.springframework.data.repository.Repository;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -328,8 +330,8 @@ public class ArchitectureTest {
ContextBasedTest.class, ContextBasedTest.class,
RbacGrantsDiagramService.class) RbacGrantsDiagramService.class)
.ignoreDependency( .ignoreDependency(
HsBookingItemEntity.class, HsBookingItem.class,
HsHostingAssetEntity.class); HsHostingAssetRbacEntity.class);
@ArchTest @ArchTest
@ -347,10 +349,21 @@ public class ArchitectureTest {
static final ArchRule tableNamesOfRbacEntitiesShouldEndWith_rv = static final ArchRule tableNamesOfRbacEntitiesShouldEndWith_rv =
classes() classes()
.that().areAnnotatedWith(Table.class) .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()) .should(haveTableNameEndingWith_rv())
.because("it's required that the table names of RBAC entities end with '_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() { static ArchCondition<JavaClass> haveTableNameEndingWith_rv() {
return new ArchCondition<>("RBAC table name end with _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.RestAssured;
import io.restassured.http.ContentType; import io.restassured.http.ContentType;
import net.hostsharing.hsadminng.HsadminNgApplication; 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.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
@ -44,10 +44,10 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
private Integer port; private Integer port;
@Autowired @Autowired
HsBookingItemRepository bookingItemRepo; HsBookingItemRealRepository realBookingItemRepo;
@Autowired @Autowired
HsBookingProjectRepository projectRepo; HsBookingProjectRealRepository realProjectRepo;
@Autowired @Autowired
HsOfficeDebitorRepository debitorRepo; HsOfficeDebitorRepository debitorRepo;
@ -65,7 +65,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream() final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid())) .map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream) .flatMap(List::stream)
.findFirst() .findFirst()
.orElseThrow(); .orElseThrow();
@ -133,7 +133,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream() final var givenProject = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid())) .map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream) .flatMap(List::stream)
.findFirst() .findFirst()
.orElseThrow(); .orElseThrow();
@ -191,9 +191,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Order(1) @Order(1)
void globalAdmin_canGetArbitraryBookingItem() { void globalAdmin_canGetArbitraryBookingItem() {
context.define("superuser-alex@hostsharing.net"); 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")) .filter(bi -> belongsToProject(bi, "D-1000111 default project"))
.map(HsBookingItemEntity::getUuid) .map(HsBookingItem::getUuid)
.findAny().orElseThrow(); .findAny().orElseThrow();
RestAssured // @formatter:off RestAssured // @formatter:off
@ -225,9 +225,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Order(2) @Order(2)
void normalUser_canNotGetUnrelatedBookingItem() { void normalUser_canNotGetUnrelatedBookingItem() {
context.define("superuser-alex@hostsharing.net"); 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")) .filter(bi -> belongsToProject(bi, "D-1000212 default project"))
.map(HsBookingItemEntity::getUuid) .map(HsBookingItem::getUuid)
.findAny().orElseThrow(); .findAny().orElseThrow();
RestAssured // @formatter:off RestAssured // @formatter:off
@ -244,7 +244,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Order(3) @Order(3)
void projectAdmin_canGetRelatedBookingItem() { void projectAdmin_canGetRelatedBookingItem() {
context.define("superuser-alex@hostsharing.net"); 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")) .filter(bi -> belongsToProject(bi, "D-1000313 default project"))
.findAny().orElseThrow(); .findAny().orElseThrow();
@ -274,9 +274,9 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
""")); // @formatter:on """)); // @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) return ofNullable(bi)
.map(HsBookingItemEntity::getProject) .map(HsBookingItem::getProject)
.filter(bp -> bp.getCaption().equals(projectCaption)) .filter(bp -> bp.getCaption().equals(projectCaption))
.isPresent(); .isPresent();
} }
@ -328,7 +328,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
// finally, the bookingItem is actually updated // finally, the bookingItem is actually updated
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get() assertThat(realBookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get()
.matches(mandate -> { .matches(mandate -> {
assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)"); assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)");
assertThat(mandate.getValidFrom()).isEqualTo("2022-11-01"); assertThat(mandate.getValidFrom()).isEqualTo("2022-11-01");
@ -358,7 +358,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(204); // @formatter:on .statusCode(204); // @formatter:on
// then the given bookingItem is gone // then the given bookingItem is gone
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isEmpty(); assertThat(realBookingItemRepo.findByUuid(givenBookingItem.getUuid())).isEmpty();
} }
@Test @Test
@ -377,18 +377,18 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(404); // @formatter:on .statusCode(404); // @formatter:on
// then the given bookingItem is still there // then the given bookingItem is still there
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isNotEmpty(); assertThat(realBookingItemRepo.findByUuid(givenBookingItem.getUuid())).isNotEmpty();
} }
} }
@SafeVarargs @SafeVarargs
private HsBookingItemEntity givenSomeNewBookingItem(final String projectCaption, private HsBookingItem givenSomeNewBookingItem(final String projectCaption,
final HsBookingItemType hsBookingItemType, final Map.Entry<String, Object>... resources) { final HsBookingItemType hsBookingItemType, final Map.Entry<String, Object>... resources) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenProject = projectRepo.findByCaption(projectCaption).stream() final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow(); .findAny().orElseThrow();
final var newBookingItem = HsBookingItemEntity.builder() final var newBookingItem = HsBookingItemRealEntity.builder()
.uuid(UUID.randomUUID()) .uuid(UUID.randomUUID())
.project(givenProject) .project(givenProject)
.type(hsBookingItemType) .type(hsBookingItemType)
@ -398,7 +398,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31"))) LocalDate.parse("2022-11-01"), LocalDate.parse("2023-03-31")))
.build(); .build();
return bookingItemRepo.save(newBookingItem); return realBookingItemRepo.save(newBookingItem);
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }

View File

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

View File

@ -17,7 +17,7 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Stream; 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.entry;
import static net.hostsharing.hsadminng.mapper.PatchMap.patchMap; import static net.hostsharing.hsadminng.mapper.PatchMap.patchMap;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
@ -29,7 +29,7 @@ import static org.mockito.Mockito.lenient;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase< class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
HsBookingItemPatchResource, HsBookingItemPatchResource,
HsBookingItemEntity HsBookingItem
> { > {
private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID(); private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID();
@ -62,15 +62,15 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
void initMocks() { void initMocks() {
lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation -> lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build()); HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsBookingItemEntity.class), any())).thenAnswer(invocation -> lenient().when(em.getReference(eq(HsBookingItem.class), any())).thenAnswer(invocation ->
HsBookingItemEntity.builder().uuid(invocation.getArgument(1)).build()); HsBookingItemRbacEntity.builder().uuid(invocation.getArgument(1)).build());
} }
@Override @Override
protected HsBookingItemEntity newInitialEntity() { protected HsBookingItem newInitialEntity() {
final var entity = new HsBookingItemEntity(); final var entity = new HsBookingItemRbacEntity();
entity.setUuid(INITIAL_BOOKING_ITEM_UUID); entity.setUuid(INITIAL_BOOKING_ITEM_UUID);
entity.setProject(TEST_PROJECT); entity.setProject(PROJECT_TEST_ENTITY);
entity.getResources().putAll(KeyValueMap.from(INITIAL_RESOURCES)); entity.getResources().putAll(KeyValueMap.from(INITIAL_RESOURCES));
entity.setCaption(INITIAL_CAPTION); entity.setCaption(INITIAL_CAPTION);
entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM)); entity.setValidity(Range.closedInfinite(GIVEN_VALID_FROM));
@ -83,7 +83,7 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
} }
@Override @Override
protected HsBookingItemEntityPatcher createPatcher(final HsBookingItemEntity bookingItem) { protected HsBookingItemEntityPatcher createPatcher(final HsBookingItem bookingItem) {
return new HsBookingItemEntityPatcher(bookingItem); return new HsBookingItemEntityPatcher(bookingItem);
} }
@ -94,19 +94,19 @@ class HsBookingItemEntityPatcherUnitTest extends PatchUnitTestBase<
"caption", "caption",
HsBookingItemPatchResource::setCaption, HsBookingItemPatchResource::setCaption,
PATCHED_CAPTION, PATCHED_CAPTION,
HsBookingItemEntity::setCaption), HsBookingItem::setCaption),
new SimpleProperty<>( new SimpleProperty<>(
"resources", "resources",
HsBookingItemPatchResource::setResources, HsBookingItemPatchResource::setResources,
PATCH_RESOURCES, PATCH_RESOURCES,
HsBookingItemEntity::putResources, HsBookingItem::putResources,
PATCHED_RESOURCES) PATCHED_RESOURCES)
.notNullable(), .notNullable(),
new JsonNullableProperty<>( new JsonNullableProperty<>(
"validto", "validto",
HsBookingItemPatchResource::setValidTo, HsBookingItemPatchResource::setValidTo,
PATCHED_VALID_TO, PATCHED_VALID_TO,
HsBookingItemEntity::setValidTo) HsBookingItem::setValidTo)
); );
} }
} }

View File

@ -10,7 +10,7 @@ import java.time.Month;
import java.util.Map; import java.util.Map;
import static java.util.Map.entry; 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 net.hostsharing.hsadminng.mapper.PostgresDateRange.toPostgresDateRange;
import static org.assertj.core.api.Assertions.assertThat; 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); private MockedStatic<LocalDate> localDateMockedStatic = Mockito.mockStatic(LocalDate.class, Mockito.CALLS_REAL_METHODS);
final HsBookingItemEntity givenBookingItem = HsBookingItemEntity.builder() final HsBookingItem givenBookingItem = HsBookingItemRbacEntity.builder()
.project(TEST_PROJECT) .project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.CLOUD_SERVER) .type(HsBookingItemType.CLOUD_SERVER)
.caption("some caption") .caption("some caption")
.resources(Map.ofEntries( .resources(Map.ofEntries(
@ -43,7 +43,7 @@ class HsBookingItemEntityUnitTest {
localDateMockedStatic.when(LocalDate::now).thenReturn(fakedToday); localDateMockedStatic.when(LocalDate::now).thenReturn(fakedToday);
// when // when
final var newBookingItem = HsBookingItemEntity.builder().build(); final var newBookingItem = HsBookingItemRbacEntity.builder().build();
// then // then
assertThat(newBookingItem.getValidity().toString()).isEqualTo("Range{lower=2024-05-01, upper=null, mask=82, clazz=class java.time.LocalDate}"); 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() { void toStringContainsAllPropertiesAndResourcesSortedByKey() {
final var result = givenBookingItem.toString(); 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 @Test

View File

@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.booking.item;
import io.hypersistence.utils.hibernate.type.range.Range; import io.hypersistence.utils.hibernate.type.range.Range;
import net.hostsharing.hsadminng.context.Context; 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.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository; import net.hostsharing.hsadminng.rbac.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
@ -39,10 +39,10 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup { class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired @Autowired
HsBookingItemRepository bookingItemRepo; HsBookingItemRbacRepository rbacBookingItemRepo;
@Autowired @Autowired
HsBookingProjectRepository projectRepo; HsBookingProjectRealRepository realProjectRepo;
@Autowired @Autowired
HsOfficeDebitorRepository debitorRepo; HsOfficeDebitorRepository debitorRepo;
@ -69,27 +69,27 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingItem() { public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingItem() {
// given // given
context("superuser-alex@hostsharing.net"); 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 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 // when
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
final var newBookingItem = HsBookingItemEntity.builder() final var newBookingItem = HsBookingItemRbacEntity.builder()
.project(givenProject) .project(givenProject)
.type(HsBookingItemType.CLOUD_SERVER) .type(HsBookingItemType.CLOUD_SERVER)
.caption("some new booking item") .caption("some new booking item")
.validity(Range.closedOpen( .validity(Range.closedOpen(
LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01")))
.build(); .build();
return toCleanup(bookingItemRepo.save(newBookingItem)); return toCleanup(rbacBookingItemRepo.save(newBookingItem));
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingItemEntity::getUuid).isNotNull(); assertThat(result.returnedValue()).isNotNull().extracting(HsBookingItem::getUuid).isNotNull();
assertThatBookingItemIsPersisted(result.returnedValue()); assertThatBookingItemIsPersisted(result.returnedValue());
assertThat(bookingItemRepo.count()).isEqualTo(count + 1); assertThat(rbacBookingItemRepo.count()).isEqualTo(count + 1);
} }
@Test @Test
@ -102,15 +102,15 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when // when
attempt(em, () -> { attempt(em, () -> {
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0); 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);
final var newBookingItem = HsBookingItemEntity.builder() final var newBookingItem = HsBookingItemRbacEntity.builder()
.project(givenProject) .project(givenProject)
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.caption("some new booking item") .caption("some new booking item")
.validity(Range.closedOpen( .validity(Range.closedOpen(
LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01"))) LocalDate.parse("2020-01-01"), LocalDate.parse("2023-01-01")))
.build(); .build();
return toCleanup(bookingItemRepo.save(newBookingItem)); return toCleanup(rbacBookingItemRepo.save(newBookingItem));
}); });
// then // then
@ -146,9 +146,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
null)); null));
} }
private void assertThatBookingItemIsPersisted(final HsBookingItemEntity saved) { private void assertThatBookingItemIsPersisted(final HsBookingItem saved) {
final var found = bookingItemRepo.findByUuid(saved.getUuid()); final var found = rbacBookingItemRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingItemEntity::toString).get().isEqualTo(saved.toString()); assertThat(found).isNotEmpty().map(HsBookingItem::toString).get().isEqualTo(saved.toString());
} }
} }
@ -160,22 +160,19 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var projectUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream() final var projectUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid())) .map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream) .flatMap(List::stream)
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
// when // when
final var result = bookingItemRepo.findAllByProjectUuid(projectUuid); final var result = rbacBookingItemRepo.findAllByProjectUuid(projectUuid);
// then // then
allTheseBookingItemsAreReturned( allTheseBookingItemsAreReturned(
result, result,
"HsBookingItemEntity(MANAGED_SERVER, separate ManagedServer, D-1000212:D-1000212 default project, [2022-10-01,), { CPU: 2, RAM: 8, SSD: 500, Traffic: 500 })", "HsBookingItem(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 })", "HsBookingItem(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 })"); "HsBookingItem(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();
} }
@Test @Test
@ -185,19 +182,19 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
final var debitor = debitorRepo.findDebitorByDebitorNumber(1000111); final var debitor = debitorRepo.findDebitorByDebitorNumber(1000111);
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:OWNER"); context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:OWNER");
final var projectUuid = debitor.stream() final var projectUuid = debitor.stream()
.map(d -> projectRepo.findAllByDebitorUuid(d.getUuid())) .map(d -> realProjectRepo.findAllByDebitorUuid(d.getUuid()))
.flatMap(List::stream) .flatMap(List::stream)
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
// when: // when:
final var result = bookingItemRepo.findAllByProjectUuid(projectUuid); final var result = rbacBookingItemRepo.findAllByProjectUuid(projectUuid);
// then: // then:
exactlyTheseBookingItemsAreReturned( exactlyTheseBookingItemsAreReturned(
result, result,
"HsBookingItemEntity(MANAGED_SERVER, separate ManagedServer, D-1000111:D-1000111 default project, [2022-10-01,), { CPU : 2, RAM : 8, SSD : 500, Traffic : 500 })", "HsBookingItem(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 })", "HsBookingItem(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(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 // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT"); 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().put("CPU", 2);
foundBookingItem.getResources().remove("SSD-storage"); foundBookingItem.getResources().remove("SSD-storage");
foundBookingItem.getResources().put("HSD-storage", 2048); foundBookingItem.getResources().put("HSD-storage", 2048);
foundBookingItem.setValidity(Range.closedOpen( foundBookingItem.setValidity(Range.closedOpen(
LocalDate.parse("2019-05-17"), LocalDate.parse("2023-01-01"))); LocalDate.parse("2019-05-17"), LocalDate.parse("2023-01-01")));
return toCleanup(bookingItemRepo.save(foundBookingItem)); return toCleanup(rbacBookingItemRepo.save(foundBookingItem));
}); });
// then // then
@ -229,10 +226,10 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
}).assertSuccessful(); }).assertSuccessful();
} }
private void assertThatBookingItemActuallyInDatabase(final HsBookingItemEntity saved) { private void assertThatBookingItemActuallyInDatabase(final HsBookingItem saved) {
final var found = bookingItemRepo.findByUuid(saved.getUuid()); final var found = rbacBookingItemRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved) assertThat(found).isNotEmpty().get().isNotSameAs(saved)
.extracting(HsBookingItemEntity::getResources) .extracting(HsBookingItem::getResources)
.extracting(Object::toString) .extracting(Object::toString)
.isEqualTo(saved.getResources().toString()); .isEqualTo(saved.getResources().toString());
} }
@ -250,14 +247,14 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
bookingItemRepo.deleteByUuid(givenBookingItem.getUuid()); rbacBookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null); context("superuser-fran@hostsharing.net", null);
return bookingItemRepo.findByUuid(givenBookingItem.getUuid()); return rbacBookingItemRepo.findByUuid(givenBookingItem.getUuid());
}).assertSuccessful().returnedValue()).isEmpty(); }).assertSuccessful().returnedValue()).isEmpty();
} }
@ -270,9 +267,9 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT"); 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 // then
@ -281,7 +278,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
"[403] Subject ", " is not allowed to delete hs_booking_item"); "[403] Subject ", " is not allowed to delete hs_booking_item");
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
return bookingItemRepo.findByUuid(givenBookingItem.getUuid()); return rbacBookingItemRepo.findByUuid(givenBookingItem.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there }).assertSuccessful().returnedValue()).isPresent(); // still there
} }
@ -296,7 +293,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
return bookingItemRepo.deleteByUuid(givenBookingItem.getUuid()); return rbacBookingItemRepo.deleteByUuid(givenBookingItem.getUuid());
}); });
// then // then
@ -314,7 +311,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
select currentTask, targetTable, targetOp select currentTask, targetTable, targetOp
from tx_journal_v from tx_journal_v
where targettable = 'hs_booking_item'; where targettable = 'hs_booking_item';
"""); """);
// when // when
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList(); @SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
@ -326,12 +323,12 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
"[creating booking-item test-data 1000313, hs_booking_item, INSERT]"); "[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(() -> { return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenProject = projectRepo.findByCaption(projectCaption).stream() final var givenProject = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow(); .findAny().orElseThrow();
final var newBookingItem = HsBookingItemEntity.builder() final var newBookingItem = HsBookingItemRbacEntity.builder()
.project(givenProject) .project(givenProject)
.type(MANAGED_SERVER) .type(MANAGED_SERVER)
.caption("some temp booking item") .caption("some temp booking item")
@ -342,23 +339,23 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
entry("SSD-storage", 256))) entry("SSD-storage", 256)))
.build(); .build();
return toCleanup(bookingItemRepo.save(newBookingItem)); return toCleanup(rbacBookingItemRepo.save(newBookingItem));
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }
void exactlyTheseBookingItemsAreReturned( void exactlyTheseBookingItemsAreReturned(
final List<HsBookingItemEntity> actualResult, final List<? extends HsBookingItem> actualResult,
final String... bookingItemNames) { final String... bookingItemNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(HsBookingItemEntity::toString) .extracting(HsBookingItem::toString)
.extracting(string-> string.replaceAll("\\s+", " ")) .extracting(string-> string.replaceAll("\\s+", " "))
.extracting(string-> string.replaceAll("\"", "")) .extracting(string-> string.replaceAll("\"", ""))
.containsExactlyInAnyOrder(bookingItemNames); .containsExactlyInAnyOrder(bookingItemNames);
} }
void allTheseBookingItemsAreReturned(final List<HsBookingItemEntity> actualResult, final String... bookingItemNames) { void allTheseBookingItemsAreReturned(final List<? extends HsBookingItem> actualResult, final String... bookingItemNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(HsBookingItemEntity::toString) .extracting(HsBookingItem::toString)
.extracting(string -> string.replaceAll("\\s+", " ")) .extracting(string -> string.replaceAll("\\s+", " "))
.extracting(string -> string.replaceAll("\"", "")) .extracting(string -> string.replaceAll("\"", ""))
.extracting(string -> string.replaceAll(" : ", ": ")) .extracting(string -> string.replaceAll(" : ", ": "))

View File

@ -7,13 +7,13 @@ import java.time.LocalDate;
import java.util.Map; import java.util.Map;
import static java.util.Map.entry; 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 @UtilityClass
public class TestHsBookingItem { public class TestHsBookingItem {
public static final HsBookingItemEntity TEST_CLOUD_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder() public static final HsBookingItemRealEntity CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY = HsBookingItemRealEntity.builder()
.project(TEST_PROJECT) .project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.CLOUD_SERVER) .type(HsBookingItemType.CLOUD_SERVER)
.caption("test cloud server booking item") .caption("test cloud server booking item")
.resources(Map.ofEntries( .resources(Map.ofEntries(
@ -25,8 +25,8 @@ public class TestHsBookingItem {
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15))) .validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
.build(); .build();
public static final HsBookingItemEntity TEST_MANAGED_SERVER_BOOKING_ITEM = HsBookingItemEntity.builder() public static final HsBookingItemRealEntity MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY = HsBookingItemRealEntity.builder()
.project(TEST_PROJECT) .project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.MANAGED_SERVER) .type(HsBookingItemType.MANAGED_SERVER)
.caption("test project booking item") .caption("test project booking item")
.resources(Map.ofEntries( .resources(Map.ofEntries(
@ -38,8 +38,8 @@ public class TestHsBookingItem {
.validity(Range.closedInfinite(LocalDate.of(2020, 1, 15))) .validity(Range.closedInfinite(LocalDate.of(2020, 1, 15)))
.build(); .build();
public static final HsBookingItemEntity TEST_MANAGED_WEBSPACE_BOOKING_ITEM = HsBookingItemEntity.builder() public static final HsBookingItemRealEntity MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY = HsBookingItemRealEntity.builder()
.parentItem(TEST_MANAGED_SERVER_BOOKING_ITEM) .parentItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsBookingItemType.MANAGED_WEBSPACE) .type(HsBookingItemType.MANAGED_WEBSPACE)
.caption("test managed webspace item") .caption("test managed webspace item")
.resources(Map.ofEntries( .resources(Map.ofEntries(

View File

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

View File

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

View File

@ -1,11 +1,14 @@
package net.hostsharing.hsadminng.hs.booking.item.validators; 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.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -17,18 +20,20 @@ import static java.util.Arrays.stream;
import static java.util.List.of; import static java.util.List.of;
import static java.util.Map.entry; import static java.util.Map.entry;
import static java.util.Map.ofEntries; 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.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_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.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD; import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.PRIVATE_CLOUD;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class)
class HsManagedServerBookingItemValidatorUnitTest { class HsManagedServerBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder() final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345) .debitorNumber(12345)
.build(); .build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder() final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor) .debitor(debitor)
.caption("Test-Project") .caption("Test-Project")
.build(); .build();
@ -36,7 +41,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
@Test @Test
void validatesProperties() { void validatesProperties() {
// given // given
final var mangedServerBookingItemEntity = HsBookingItemEntity.builder() final var mangedServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER) .type(MANAGED_SERVER)
.project(project) .project(project)
.resources(Map.ofEntries( .resources(Map.ofEntries(
@ -48,9 +53,10 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("SLA-EMail", true) entry("SLA-EMail", true)
)) ))
.build(); .build();
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when // when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(mangedServerBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, mangedServerBookingItemEntity);
// then // then
assertThat(result).containsExactly("'D-12345:Test-Project:null.resources.SLA-EMail' is expected to be false because SLA-Platform=BASIC but is true"); 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 @Test
void validatesExceedingPropertyTotals() { void validatesExceedingPropertyTotals() {
// given // given
final var subCloudServerBookingItemEntity = HsBookingItemEntity.builder() final var subCloudServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER) .type(CLOUD_SERVER)
.resources(ofEntries( .resources(ofEntries(
entry("CPU", 2), entry("CPU", 2),
@ -89,7 +95,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 2500) entry("Traffic", 2500)
)) ))
.build(); .build();
final HsBookingItemEntity subManagedServerBookingItemEntity = HsBookingItemEntity.builder() final HsBookingItemRealEntity subManagedServerBookingItemEntity = HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER) .type(MANAGED_SERVER)
.resources(ofEntries( .resources(ofEntries(
entry("CPU", 3), entry("CPU", 3),
@ -98,7 +104,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 3000) entry("Traffic", 3000)
)) ))
.build(); .build();
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder() final var privateCloudBookingItemEntity = HsBookingItemRealEntity.builder()
.type(PRIVATE_CLOUD) .type(PRIVATE_CLOUD)
.project(project) .project(project)
.resources(ofEntries( .resources(ofEntries(
@ -116,8 +122,10 @@ class HsManagedServerBookingItemValidatorUnitTest {
subManagedServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity); subManagedServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity); subCloudServerBookingItemEntity.setParentItem(privateCloudBookingItemEntity);
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when // when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(subManagedServerBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, subManagedServerBookingItemEntity);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(
@ -131,7 +139,7 @@ class HsManagedServerBookingItemValidatorUnitTest {
@Test @Test
void validatesExceedingTotals() { void validatesExceedingTotals() {
// given // given
final var managedWebspaceBookingItem = HsBookingItemEntity.builder() final var managedWebspaceBookingItem = HsBookingItemRealEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.project(project) .project(project)
.caption("test Managed-Webspace") .caption("test Managed-Webspace")
@ -140,7 +148,8 @@ class HsManagedServerBookingItemValidatorUnitTest {
entry("Traffic", 1000), entry("Traffic", 1000),
entry("Multi", 1) entry("Multi", 1)
)) ))
.relatedHostingAsset(HsHostingAssetEntity.builder() .build();
final var em = createEntityManagerMockWithAssetQueryFake(HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_WEBSPACE) .type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("abc00") .identifier("abc00")
.subHostingAssets(concat( .subHostingAssets(concat(
@ -157,13 +166,11 @@ class HsManagedServerBookingItemValidatorUnitTest {
"%c%c.example.com", "%c%c.example.com",
10, HsHostingAssetType.EMAIL_ADDRESS 10, HsHostingAssetType.EMAIL_ADDRESS
) )
)) ))
.build() .build());
)
.build();
// when // when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(managedWebspaceBookingItem); final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, managedWebspaceBookingItem);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(
@ -175,47 +182,48 @@ class HsManagedServerBookingItemValidatorUnitTest {
} }
@SafeVarargs @SafeVarargs
private List<HsHostingAssetEntity> concat(final List<HsHostingAssetEntity>... hostingAssets) { private List<HsHostingAssetRealEntity> concat(final List<HsHostingAssetRealEntity>... hostingAssets) {
return stream(hostingAssets) return stream(hostingAssets)
.flatMap(Collection::stream) .flatMap(Collection::stream)
.collect(Collectors.toList()); .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) { final String identifierPattern) {
return IntStream.range(0, count) return IntStream.range(0, count)
.mapToObj(number -> HsHostingAssetEntity.builder() .mapToObj(number -> (HsHostingAssetRealEntity) HsHostingAssetRealEntity.builder()
.type(hostingAssetType) .type(hostingAssetType)
.identifier(identifierPattern.formatted((number/'a')+'a', (number%'a')+'a')) .identifier(identifierPattern.formatted((number/'a')+'a', (number%'a')+'a'))
.build()) .build())
.toList(); .toList();
} }
private List<HsHostingAssetEntity> generateDbUsersWithDatabases( private List<HsHostingAssetRealEntity> generateDbUsersWithDatabases(
final int userCount, final int userCount,
final HsHostingAssetType directAssetType, final HsHostingAssetType directAssetType,
final String directAssetIdentifierFormat, final String directAssetIdentifierFormat,
final int dbCount, final int dbCount,
final HsHostingAssetType subAssetType) { final HsHostingAssetType subAssetType) {
return IntStream.range(0, userCount) final List<HsHostingAssetRealEntity> list = IntStream.range(0, userCount)
.mapToObj(n -> HsHostingAssetEntity.builder() .mapToObj(n -> HsHostingAssetRealEntity.builder()
.type(directAssetType) .type(directAssetType)
.identifier(directAssetIdentifierFormat.formatted((n/'a')+'a', (n%'a')+'a')) .identifier(directAssetIdentifierFormat.formatted((n / 'a') + 'a', (n % 'a') + 'a'))
.subHostingAssets( .subHostingAssets(
generate(dbCount, subAssetType, "%c%c.example.com".formatted((n/'a')+'a', (n%'a')+'a')) generate(dbCount, subAssetType, "%c%c.example.com" .formatted((n / 'a') + 'a', (n % 'a') + 'a'))
) )
.build()) .build())
.toList(); .toList();
return list;
} }
private List<HsHostingAssetEntity> generateDomainEmailSetupsWithEMailAddresses( private List<HsHostingAssetRealEntity> generateDomainEmailSetupsWithEMailAddresses(
final int domainCount, final int domainCount,
final HsHostingAssetType directAssetType, final HsHostingAssetType directAssetType,
final String directAssetIdentifierFormat, final String directAssetIdentifierFormat,
final int emailAddressCount, final int emailAddressCount,
final HsHostingAssetType subAssetType) { final HsHostingAssetType subAssetType) {
return IntStream.range(0, domainCount) return IntStream.range(0, domainCount)
.mapToObj(n -> HsHostingAssetEntity.builder() .mapToObj(n -> HsHostingAssetRealEntity.builder()
.type(directAssetType) .type(directAssetType)
.identifier(directAssetIdentifierFormat.formatted((n/'a')+'a', (n%'a')+'a')) .identifier(directAssetIdentifierFormat.formatted((n/'a')+'a', (n%'a')+'a'))
.subHostingAssets( .subHostingAssets(

View File

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

View File

@ -1,17 +1,19 @@
package net.hostsharing.hsadminng.hs.booking.item.validators; package net.hostsharing.hsadminng.hs.booking.item.validators;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity; import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealEntity;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import static java.util.List.of; import static java.util.List.of;
import static java.util.Map.entry; import static java.util.Map.entry;
import static java.util.Map.ofEntries; 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.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType.MANAGED_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.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; import static org.assertj.core.api.Assertions.assertThat;
class HsPrivateCloudBookingItemValidatorUnitTest { class HsPrivateCloudBookingItemValidatorUnitTest {
@ -19,17 +21,18 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder() final HsBookingDebitorEntity debitor = HsBookingDebitorEntity.builder()
.debitorNumber(12345) .debitorNumber(12345)
.build(); .build();
final HsBookingProjectEntity project = HsBookingProjectEntity.builder() final HsBookingProjectRealEntity project = HsBookingProjectRealEntity.builder()
.debitor(debitor) .debitor(debitor)
.caption("Test-Project") .caption("Test-Project")
.build(); .build();
private EntityManager em;
@Test @Test
void validatesPropertyTotals() { void validatesPropertyTotals() {
// given // given
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder() final var privateCloudBookingItemEntity = HsBookingItemRealEntity.builder()
.type(PRIVATE_CLOUD) .type(PRIVATE_CLOUD)
.project(TEST_PROJECT) .project(PROJECT_TEST_ENTITY)
.caption("myPC") .caption("myPC")
.resources(ofEntries( .resources(ofEntries(
entry("CPU", 4), entry("CPU", 4),
@ -40,7 +43,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", 2) entry("SLA-EMail", 2)
)) ))
.subBookingItems(of( .subBookingItems(of(
HsBookingItemEntity.builder() HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER) .type(MANAGED_SERVER)
.caption("myMS-1") .caption("myMS-1")
.resources(ofEntries( .resources(ofEntries(
@ -52,7 +55,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", true) entry("SLA-EMail", true)
)) ))
.build(), .build(),
HsBookingItemEntity.builder() HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER) .type(CLOUD_SERVER)
.caption("myMS-2") .caption("myMS-2")
.resources(ofEntries( .resources(ofEntries(
@ -68,7 +71,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, privateCloudBookingItemEntity);
// then // then
assertThat(result).isEmpty(); assertThat(result).isEmpty();
@ -77,7 +80,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
@Test @Test
void validatesExceedingPropertyTotals() { void validatesExceedingPropertyTotals() {
// given // given
final var privateCloudBookingItemEntity = HsBookingItemEntity.builder() final var privateCloudBookingItemEntity = HsBookingItemRealEntity.builder()
.project(project) .project(project)
.type(PRIVATE_CLOUD) .type(PRIVATE_CLOUD)
.caption("myPC") .caption("myPC")
@ -90,7 +93,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", 1) entry("SLA-EMail", 1)
)) ))
.subBookingItems(of( .subBookingItems(of(
HsBookingItemEntity.builder() HsBookingItemRealEntity.builder()
.type(MANAGED_SERVER) .type(MANAGED_SERVER)
.caption("myMS-1") .caption("myMS-1")
.resources(ofEntries( .resources(ofEntries(
@ -102,7 +105,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
entry("SLA-EMail", true) entry("SLA-EMail", true)
)) ))
.build(), .build(),
HsBookingItemEntity.builder() HsBookingItemRealEntity.builder()
.type(CLOUD_SERVER) .type(CLOUD_SERVER)
.caption("myMS-2") .caption("myMS-2")
.resources(ofEntries( .resources(ofEntries(
@ -122,7 +125,7 @@ class HsPrivateCloudBookingItemValidatorUnitTest {
.build(); .build();
// when // when
final var result = HsBookingItemEntityValidatorRegistry.doValidate(privateCloudBookingItemEntity); final var result = HsBookingItemEntityValidatorRegistry.doValidate(em, privateCloudBookingItemEntity);
// then // then
assertThat(result).containsExactlyInAnyOrder( assertThat(result).containsExactlyInAnyOrder(

View File

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

View File

@ -23,7 +23,7 @@ import static org.mockito.Mockito.lenient;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase< class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
HsBookingProjectPatchResource, HsBookingProjectPatchResource,
HsBookingProjectEntity HsBookingProject
> { > {
private static final UUID INITIAL_BOOKING_PROJECT_UUID = UUID.randomUUID(); private static final UUID INITIAL_BOOKING_PROJECT_UUID = UUID.randomUUID();
@ -38,13 +38,11 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
void initMocks() { void initMocks() {
lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation -> lenient().when(em.getReference(eq(HsOfficeDebitorEntity.class), any())).thenAnswer(invocation ->
HsOfficeDebitorEntity.builder().uuid(invocation.getArgument(1)).build()); 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 @Override
protected HsBookingProjectEntity newInitialEntity() { protected HsBookingProject newInitialEntity() {
final var entity = new HsBookingProjectEntity(); final var entity = new HsBookingProjectRbacEntity();
entity.setUuid(INITIAL_BOOKING_PROJECT_UUID); entity.setUuid(INITIAL_BOOKING_PROJECT_UUID);
entity.setDebitor(TEST_BOOKING_DEBITOR); entity.setDebitor(TEST_BOOKING_DEBITOR);
entity.setCaption(INITIAL_CAPTION); entity.setCaption(INITIAL_CAPTION);
@ -57,7 +55,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
} }
@Override @Override
protected HsBookingProjectEntityPatcher createPatcher(final HsBookingProjectEntity bookingProject) { protected HsBookingProjectEntityPatcher createPatcher(final HsBookingProject bookingProject) {
return new HsBookingProjectEntityPatcher(bookingProject); return new HsBookingProjectEntityPatcher(bookingProject);
} }
@ -68,7 +66,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
"caption", "caption",
HsBookingProjectPatchResource::setCaption, HsBookingProjectPatchResource::setCaption,
PATCHED_CAPTION, 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 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; import static org.assertj.core.api.Assertions.assertThat;
class HsBookingProjectEntityUnitTest { class HsBookingProjectEntityUnitTest {
final HsBookingProjectEntity givenBookingProject = HsBookingProjectEntity.builder()
.debitor(TEST_BOOKING_DEBITOR)
.caption("some caption")
.build();
@Test @Test
void toStringContainsAllPropertiesAndResourcesSortedByKey() { 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 @Test
void toShortStringContainsOnlyMemberNumberAndCaption() { 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 net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; 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.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
@ -32,10 +34,10 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithCleanup { class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired @Autowired
HsBookingProjectRepository bookingProjectRepo; HsBookingProjectRealRepository realProjectRepo;
@Autowired @Autowired
HsBookingProjectRepository projectRepo; HsBookingProjectRbacRepository rbacProjectRepo;
@Autowired @Autowired
HsBookingDebitorRepository debitorRepo; HsBookingDebitorRepository debitorRepo;
@ -61,24 +63,24 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
@Test @Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject() { public void testHostsharingAdmin_withoutAssumedRole_canCreateNewBookingProject() {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net"); // TODO.test: remove once we have a realDebitorRepo
final var count = bookingProjectRepo.count(); final var count = realProjectRepo.count();
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0); final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
// when // when
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
final var newBookingProject = HsBookingProjectEntity.builder() final var newBookingProject = HsBookingProjectRbacEntity.builder()
.debitor(givenDebitor) .debitor(givenDebitor)
.caption("some new booking project") .caption("some new booking project")
.build(); .build();
return toCleanup(bookingProjectRepo.save(newBookingProject)); return toCleanup(rbacProjectRepo.save(newBookingProject));
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsBookingProjectEntity::getUuid).isNotNull(); assertThat(result.returnedValue()).isNotNull().extracting(HsBookingProject::getUuid).isNotNull();
assertThatBookingProjectIsPersisted(result.returnedValue()); assertThatBookingProjectIsPersisted(result.returnedValue());
assertThat(bookingProjectRepo.count()).isEqualTo(count + 1); assertThat(realProjectRepo.count()).isEqualTo(count + 1);
} }
@Test @Test
@ -93,11 +95,11 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when // when
attempt(em, () -> { attempt(em, () -> {
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0); final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
final var newBookingProject = HsBookingProjectEntity.builder() final var newBookingProject = HsBookingProjectRbacEntity.builder()
.debitor(givenDebitor) .debitor(givenDebitor)
.caption("some new booking project") .caption("some new booking project")
.build(); .build();
return toCleanup(bookingProjectRepo.save(newBookingProject)); return toCleanup(rbacProjectRepo.save(newBookingProject));
}); });
// then // then
@ -135,33 +137,35 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
null)); null));
} }
private void assertThatBookingProjectIsPersisted(final HsBookingProjectEntity saved) { private void assertThatBookingProjectIsPersisted(final HsBookingProject saved) {
final var found = bookingProjectRepo.findByUuid(saved.getUuid()); final var found = rbacProjectRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsBookingProjectEntity::toString).get().isEqualTo(saved.toString()); assertThat(found).isNotEmpty().map(HsBookingProject::toString).get().isEqualTo(saved.toString());
} }
} }
@Nested @Nested
class FindByDebitorUuid { class FindByDebitorUuid {
@Test @ParameterizedTest
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor() { @EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor(final TestCase testCase) {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var debitorUuid = debitorRepo.findByDebitorNumber(1000212).stream() final var debitorUuid = debitorRepo.findByDebitorNumber(1000212).stream()
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
// when // when
final var result = bookingProjectRepo.findAllByDebitorUuid(debitorUuid); final var result = repoUnderTest(testCase).findAllByDebitorUuid(debitorUuid);
// then // then
allTheseBookingProjectsAreReturned( allTheseBookingProjectsAreReturned(
result, result,
"HsBookingProjectEntity(D-1000212, D-1000212 default project)"); "HsBookingProject(D-1000212, D-1000212 default project)");
} }
@Test @ParameterizedTest
public void packetAgent_canViewOnlyRelatedBookingProjects() { @EnumSource(TestCase.class)
public void packetAgent_canViewOnlyRelatedBookingProjects(final TestCase testCase) {
// given: // given:
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT"); context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
@ -169,50 +173,52 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
// when: // when:
final var result = bookingProjectRepo.findAllByDebitorUuid(debitorUuid); final var result = repoUnderTest(testCase).findAllByDebitorUuid(debitorUuid);
// then: // then:
exactlyTheseBookingProjectsAreReturned( assertResult(testCase, result,
result, "HsBookingProject(D-1000111, D-1000111 default project)");
"HsBookingProjectEntity(D-1000111, D-1000111 default project)");
} }
} }
@Nested @Nested
class UpdateBookingProject { class UpdateBookingProject {
@Test @ParameterizedTest
public void hostsharingAdmin_canUpdateArbitraryBookingProject() { @EnumSource(TestCase.class)
public void bookingProjectAdmin_canUpdateArbitraryBookingProject(final TestCase testCase) {
// given // given
final var givenBookingProjectUuid = givenSomeTemporaryBookingProject(1000111).getUuid(); final var givenBookingProjectUuid = givenSomeTemporaryBookingProject(1000111).getUuid();
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-sometempproject:ADMIN");
final var foundBookingProject = em.find(HsBookingProjectEntity.class, givenBookingProjectUuid); final var foundBookingProject = em.find(HsBookingProjectRbacEntity.class, givenBookingProjectUuid);
return toCleanup(bookingProjectRepo.save(foundBookingProject)); foundBookingProject.setCaption("updated caption");
return toCleanup(repoUnderTest(testCase).save(foundBookingProject));
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
jpaAttempt.transacted(() -> { assertThat(result.returnedValue().getCaption()).isEqualTo("updated caption");
context("superuser-alex@hostsharing.net"); assertThatBookingProjectActuallyInDatabase(result.returnedValue());
assertThatBookingProjectActuallyInDatabase(result.returnedValue());
}).assertSuccessful();
} }
private void assertThatBookingProjectActuallyInDatabase(final HsBookingProjectEntity saved) { private void assertThatBookingProjectActuallyInDatabase(final HsBookingProject saved) {
final var found = bookingProjectRepo.findByUuid(saved.getUuid()); jpaAttempt.transacted(() -> {
assertThat(found).isNotEmpty().get().isNotSameAs(saved) final var found = realProjectRepo.findByUuid(saved.getUuid());
.extracting(Object::toString).isEqualTo(saved.toString()); assertThat(found).isNotEmpty().get().isNotSameAs(saved)
.extracting(Object::toString).isEqualTo(saved.toString());
}).assertSuccessful();
} }
} }
@Nested @Nested
class DeleteByUuid { class DeleteByUuid {
@Test @ParameterizedTest
public void globalAdmin_withoutAssumedRole_canDeleteAnyBookingProject() { @EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canDeleteAnyBookingProject(final TestCase testCase) {
// given // given
context("superuser-alex@hostsharing.net", null); context("superuser-alex@hostsharing.net", null);
final var givenBookingProject = givenSomeTemporaryBookingProject(1000111); final var givenBookingProject = givenSomeTemporaryBookingProject(1000111);
@ -220,14 +226,14 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid()); repoUnderTest(testCase).deleteByUuid(givenBookingProject.getUuid());
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null); context("superuser-fran@hostsharing.net", null);
return bookingProjectRepo.findByUuid(givenBookingProject.getUuid()); return rbacProjectRepo.findByUuid(givenBookingProject.getUuid());
}).assertSuccessful().returnedValue()).isEmpty(); }).assertSuccessful().returnedValue()).isEmpty();
} }
@ -239,9 +245,9 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-sometempproject:AGENT"); 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 // then
@ -250,12 +256,13 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
"[403] Subject ", " is not allowed to delete hs_booking_project"); "[403] Subject ", " is not allowed to delete hs_booking_project");
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
return bookingProjectRepo.findByUuid(givenBookingProject.getUuid()); return rbacProjectRepo.findByUuid(givenBookingProject.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there }).assertSuccessful().returnedValue()).isPresent(); // still there
} }
@Test @ParameterizedTest
public void deletingABookingProjectAlsoDeletesRelatedRolesAndGrants() { @EnumSource(TestCase.class)
public void deletingABookingProjectAlsoDeletesRelatedRolesAndGrants(final TestCase testCase) {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll())); final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
@ -265,7 +272,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
return bookingProjectRepo.deleteByUuid(givenBookingProject.getUuid()); return repoUnderTest(testCase).deleteByUuid(givenBookingProject.getUuid());
}); });
// then // then
@ -295,32 +302,78 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
"[creating booking-project test-data 1000313, hs_booking_project, INSERT]"); "[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(() -> { return jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).get(0); final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).get(0);
final var newBookingProject = HsBookingProjectEntity.builder() final var newBookingProject = HsBookingProjectRealEntity.builder()
.debitor(givenDebitor) .debitor(givenDebitor)
.caption("some temp project") .caption("some temp project")
.build(); .build();
return toCleanup(bookingProjectRepo.save(newBookingProject)); return toCleanup(realProjectRepo.save(newBookingProject));
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }
void exactlyTheseBookingProjectsAreReturned( void exactlyTheseBookingProjectsAreReturned(
final List<HsBookingProjectEntity> actualResult, final List<? extends HsBookingProject> actualResult,
final String... bookingProjectNames) { final String... bookingProjectNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(HsBookingProjectEntity::toString) .extracting(HsBookingProject::toString)
.containsExactlyInAnyOrder(bookingProjectNames); .containsExactlyInAnyOrder(bookingProjectNames);
} }
void allTheseBookingProjectsAreReturned( void allTheseBookingProjectsAreReturned(
final List<HsBookingProjectEntity> actualResult, final List<? extends HsBookingProject> actualResult,
final String... bookingProjectNames) { final String... bookingProjectNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(HsBookingProjectEntity::toString) .extracting(HsBookingProject::toString)
.contains(bookingProjectNames); .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 @UtilityClass
public class TestHsBookingProject { public class TestHsBookingProject {
public static final HsBookingProjectRealEntity PROJECT_TEST_ENTITY = HsBookingProjectRealEntity.builder()
public static final HsBookingProjectEntity TEST_PROJECT = HsBookingProjectEntity.builder()
.debitor(TEST_BOOKING_DEBITOR) .debitor(TEST_BOOKING_DEBITOR)
.caption("test project") .caption("test project")
.build(); .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 io.restassured.http.ContentType;
import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.HsadminNgApplication;
import net.hostsharing.hsadminng.hash.HashGenerator; import net.hostsharing.hsadminng.hash.HashGenerator;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
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.item.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository; import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRealRepository;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacRepository; import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRealRepository;
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup; import net.hostsharing.hsadminng.rbac.test.ContextBasedTestWithCleanup;
import net.hostsharing.hsadminng.rbac.test.JpaAttempt; import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.ClassOrderer; import org.junit.jupiter.api.ClassOrderer;
@ -50,19 +50,16 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
private Integer port; private Integer port;
@Autowired @Autowired
HsHostingAssetRepository assetRepo; HsHostingAssetRealRepository realAssetRepo;
@Autowired @Autowired
HsBookingItemRepository bookingItemRepo; HsBookingItemRealRepository realBookingItemRepo;
@Autowired @Autowired
HsBookingProjectRepository projectRepo; HsBookingProjectRealRepository realProjectRepo;
@Autowired @Autowired
HsOfficeDebitorRepository debitorRepo; HsOfficeContactRealRepository realContactRepo;
@Autowired
HsOfficeContactRbacRepository contactRepo;
@Autowired @Autowired
JpaAttempt jpaAttempt; JpaAttempt jpaAttempt;
@ -76,7 +73,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
// given // given
context("superuser-alex@hostsharing.net"); 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(); .findAny().orElseThrow();
RestAssured // @formatter:off RestAssured // @formatter:off
@ -189,13 +186,12 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
final var newWebspace = UUID.fromString( final var newWebspace = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1)); location.substring(location.lastIndexOf('/') + 1));
assertThat(newWebspace).isNotNull(); assertThat(newWebspace).isNotNull();
toCleanup(HsHostingAssetEntity.class, newWebspace); toCleanup(HsHostingAssetRbacEntity.class, newWebspace);
} }
@Test @Test
void parentAssetAgent_canAddSubAsset() { void parentAssetAgent_canAddSubAsset() {
context.define("superuser-alex@hostsharing.net");
final var givenParentAsset = givenParentAsset(MANAGED_WEBSPACE, "fir01"); final var givenParentAsset = givenParentAsset(MANAGED_WEBSPACE, "fir01");
final var location = RestAssured // @formatter:off final var location = RestAssured // @formatter:off
@ -273,7 +269,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
final var newWebspace = UUID.fromString( final var newWebspace = UUID.fromString(
location.substring(location.lastIndexOf('/') + 1)); location.substring(location.lastIndexOf('/') + 1));
assertThat(newWebspace).isNotNull(); assertThat(newWebspace).isNotNull();
toCleanup(HsHostingAssetEntity.class, newWebspace); toCleanup(HsHostingAssetRbacEntity.class, newWebspace);
} }
@Test @Test
@ -320,18 +316,18 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void totalsLimitValidationsArePerformend_whenAddingAsset() { void totalsLimitValidationsArePerformend_whenAddingAsset() {
context.define("superuser-alex@hostsharing.net"); 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")) assertThat(givenHostingAsset.getBookingItem().getResources().get("Multi"))
.as("precondition failed") .as("precondition failed")
.isEqualTo(1); .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; final var UNIX_USER_PER_MULTI_OPTION = 25;
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION -preExistingUnixUserCount+1; ++n) { for (int n = 0; n < UNIX_USER_PER_MULTI_OPTION -preExistingUnixUserCount+1; ++n) {
toCleanup(assetRepo.save( toCleanup(realAssetRepo.save(
HsHostingAssetEntity.builder() HsHostingAssetRealEntity.builder()
.type(UNIX_USER) .type(UNIX_USER)
.parentAsset(givenHostingAsset) .parentAsset(givenHostingAsset)
.identifier("fir01-%2d".formatted(n)) .identifier("fir01-%2d".formatted(n))
@ -375,7 +371,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Test @Test
void globalAdmin_canGetArbitraryAsset() { void globalAdmin_canGetArbitraryAsset() {
context.define("superuser-alex@hostsharing.net"); 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")) .filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000111 default project"))
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
@ -399,9 +395,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Test @Test
void normalUser_canNotGetUnrelatedAsset() { void normalUser_canNotGetUnrelatedAsset() {
context.define("superuser-alex@hostsharing.net"); 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")) .filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000212 default project"))
.map(HsHostingAssetEntity::getUuid) .map(HsHostingAssetRealEntity::getUuid)
.findAny().orElseThrow(); .findAny().orElseThrow();
RestAssured // @formatter:off RestAssured // @formatter:off
@ -417,7 +413,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
@Test @Test
void projectAgentUser_canGetRelatedAsset() { void projectAgentUser_canGetRelatedAsset() {
context.define("superuser-alex@hostsharing.net"); 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")) .filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000313 default project"))
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
@ -449,7 +445,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void globalAdmin_canPatchAllUpdatablePropertiesOfAsset() { void globalAdmin_canPatchAllUpdatablePropertiesOfAsset() {
final var givenAsset = givenSomeTemporaryHostingAsset(() -> final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder() HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID()) .uuid(UUID.randomUUID())
.bookingItem(givenSomeNewBookingItem( .bookingItem(givenSomeNewBookingItem(
"D-1000111 default project", "D-1000111 default project",
@ -510,8 +506,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
// finally, the asset is actually updated // finally, the asset is actually updated
em.clear(); em.clear();
context.define("superuser-alex@hostsharing.net"); assertThat(realAssetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
.matches(asset -> { .matches(asset -> {
assertThat(asset.getAlarmContact()).isNotNull() assertThat(asset.getAlarmContact()).isNotNull()
.extracting(c -> c.getEmailAddresses().get("main")) .extracting(c -> c.getEmailAddresses().get("main"))
@ -533,10 +528,10 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void assetAdmin_canPatchAllUpdatablePropertiesOfAsset() { void assetAdmin_canPatchAllUpdatablePropertiesOfAsset() {
final var givenAsset = givenSomeTemporaryHostingAsset(() -> final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder() HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID()) .uuid(UUID.randomUUID())
.type(UNIX_USER) .type(UNIX_USER)
.parentAsset(givenHostingAsset(MANAGED_WEBSPACE, "fir01")) .parentAsset(givenRealHostingAsset(MANAGED_WEBSPACE, "fir01"))
.identifier("fir01-temp") .identifier("fir01-temp")
.caption("some test-unix-user") .caption("some test-unix-user")
.build()); .build());
@ -586,8 +581,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
// finally, the asset is actually updated // finally, the asset is actually updated
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); return realAssetRepo.findByUuid(givenAsset.getUuid());
return assetRepo.findByUuid(givenAsset.getUuid());
}).returnedValue()).isPresent().get() }).returnedValue()).isPresent().get()
.matches(asset -> { .matches(asset -> {
assertThat(asset.getCaption()).isEqualTo("some patched test-unix-user"); assertThat(asset.getCaption()).isEqualTo("some patched test-unix-user");
@ -611,7 +605,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
void globalAdmin_canDeleteArbitraryAsset() { void globalAdmin_canDeleteArbitraryAsset() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAsset = givenSomeTemporaryHostingAsset(() -> final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder() HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID()) .uuid(UUID.randomUUID())
.bookingItem(givenSomeNewBookingItem( .bookingItem(givenSomeNewBookingItem(
"D-1000111 default project", "D-1000111 default project",
@ -637,14 +631,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(204); // @formatter:on .statusCode(204); // @formatter:on
// then the given assets is gone // then the given assets is gone
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isEmpty(); assertThat(realAssetRepo.findByUuid(givenAsset.getUuid())).isEmpty();
} }
@Test @Test
void normalUser_canNotDeleteUnrelatedAsset() { void normalUser_canNotDeleteUnrelatedAsset() {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var givenAsset = givenSomeTemporaryHostingAsset(() -> final var givenAsset = givenSomeTemporaryHostingAsset(() ->
HsHostingAssetEntity.builder() HsHostingAssetRealEntity.builder()
.uuid(UUID.randomUUID()) .uuid(UUID.randomUUID())
.bookingItem(givenSomeNewBookingItem( .bookingItem(givenSomeNewBookingItem(
"D-1000111 default project", "D-1000111 default project",
@ -670,40 +664,40 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
.statusCode(404); // @formatter:on .statusCode(404); // @formatter:on
// then the given asset is still there // 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) { HsHostingAssetRealEntity givenRealHostingAsset(final HsHostingAssetType type, final String identifier) {
return assetRepo.findByIdentifier(identifier).stream() return realAssetRepo.findByIdentifier(identifier).stream()
.filter(ha -> ha.getType() == type) .filter(ha -> ha.getType() == type)
.findAny().orElseThrow(); .findAny().orElseThrow();
} }
HsBookingItemEntity newBookingItem( HsBookingItem newBookingItem(
final String projectCaption, final String projectCaption,
final HsBookingItemType type, final String bookingItemCaption, final Map<String, Object> resources) { final HsBookingItemType type, final String bookingItemCaption, final Map<String, Object> resources) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
final var project = projectRepo.findByCaption(projectCaption).stream() final var project = realProjectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow(); .findAny().orElseThrow();
final var bookingItem = HsBookingItemEntity.builder() final var bookingItem = HsBookingItemRealEntity.builder()
.project(project) .project(project)
.type(type) .type(type)
.caption(bookingItemCaption) .caption(bookingItemCaption)
.resources(resources) .resources(resources)
.build(); .build();
return toCleanup(bookingItemRepo.save(bookingItem)); return toCleanup(realBookingItemRepo.save(bookingItem));
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }
HsBookingItemEntity givenSomeNewBookingItem( HsBookingItemRealEntity givenSomeNewBookingItem(
final String projectCaption, final String projectCaption,
final HsBookingItemType bookingItemType, final HsBookingItemType bookingItemType,
final String bookingItemCaption) { final String bookingItemCaption) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); 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) { final var resources = switch (bookingItemType) {
case MANAGED_SERVER -> Map.<String, Object>ofEntries(entry("CPU", 1), case MANAGED_SERVER -> Map.<String, Object>ofEntries(entry("CPU", 1),
entry("RAM", 20), entry("RAM", 20),
@ -711,34 +705,34 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
entry("Traffic", 250)); entry("Traffic", 250));
default -> new HashMap<String, Object>(); default -> new HashMap<String, Object>();
}; };
final var newBookingItem = HsBookingItemEntity.builder() final var newBookingItem = HsBookingItemRealEntity.builder()
.project(project) .project(project)
.type(bookingItemType) .type(bookingItemType)
.caption(bookingItemCaption) .caption(bookingItemCaption)
.resources(resources) .resources(resources)
.build(); .build();
return toCleanup(bookingItemRepo.save(newBookingItem)); return toCleanup(realBookingItemRepo.save(newBookingItem));
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }
HsHostingAssetEntity givenParentAsset(final HsHostingAssetType assetType, final String assetIdentifier) { HsHostingAssetRealEntity givenParentAsset(final HsHostingAssetType assetType, final String assetIdentifier) {
final var givenAsset = assetRepo.findByIdentifier(assetIdentifier).stream() final var givenAsset = realAssetRepo.findByIdentifier(assetIdentifier).stream()
.filter(a -> a.getType() == assetType) .filter(a -> a.getType() == assetType)
.findAny().orElseThrow(); .findAny().orElseThrow();
return givenAsset; return givenAsset;
} }
private HsHostingAssetEntity givenSomeTemporaryHostingAsset(final Supplier<HsHostingAssetEntity> newAsset) { private HsHostingAssetRealEntity givenSomeTemporaryHostingAsset(final Supplier<HsHostingAssetRealEntity> newAsset) {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net"); // needed to determine creator
return toCleanup(assetRepo.save(newAsset.get())); return toCleanup(realAssetRepo.save(newAsset.get()));
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }
private HsOfficeContactRbacEntity givenContact() { private HsOfficeContactRealEntity givenContact() {
return jpaAttempt.transacted(() -> { return jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net"); // needed to determine creator
return contactRepo.findContactByOptionalCaptionLike("second").stream().findFirst().orElseThrow(); return realContactRepo.findContactByOptionalCaptionLike("second").stream().findFirst().orElseThrow();
}).returnedValue(); }).returnedValue();
} }

View File

@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import net.hostsharing.hsadminng.context.Context; 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.Array;
import net.hostsharing.hsadminng.mapper.Mapper; import net.hostsharing.hsadminng.mapper.Mapper;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -28,10 +28,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import static java.util.Map.entry; 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.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.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.TestHsHostingAssetEntities.TEST_MANAGED_WEBSPACE_HOSTING_ASSET; 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.hs.office.contact.HsOfficeContactRealTestEntity.TEST_REAL_CONTACT;
import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals; import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -62,17 +62,20 @@ public class HsHostingAssetControllerRestTest {
@MockBean @MockBean
@SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController @SuppressWarnings("unused") // bean needs to be present for HsHostingAssetController
private HsBookingItemRepository bookingItemRepo; private HsBookingItemRealRepository realBookingItemRepo;
@MockBean @MockBean
private HsHostingAssetRepository hostingAssetRepo; private HsHostingAssetRealRepository realAssetRepo;
@MockBean
private HsHostingAssetRbacRepository rbacAssetRepo;
enum ListTestCases { enum ListTestCases {
CLOUD_SERVER( CLOUD_SERVER(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.CLOUD_SERVER) .type(HsHostingAssetType.CLOUD_SERVER)
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM) .bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.identifier("vm1234") .identifier("vm1234")
.caption("some fake cloud-server") .caption("some fake cloud-server")
.alarmContact(TEST_REAL_CONTACT) .alarmContact(TEST_REAL_CONTACT)
@ -96,9 +99,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
MANAGED_SERVER( MANAGED_SERVER(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MANAGED_SERVER) .type(HsHostingAssetType.MANAGED_SERVER)
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM) .bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.identifier("vm1234") .identifier("vm1234")
.caption("some fake managed-server") .caption("some fake managed-server")
.alarmContact(TEST_REAL_CONTACT) .alarmContact(TEST_REAL_CONTACT)
@ -131,9 +134,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
UNIX_USER( UNIX_USER(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.UNIX_USER) .type(HsHostingAssetType.UNIX_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("xyz00-office") .identifier("xyz00-office")
.caption("some fake Unix-User") .caption("some fake Unix-User")
.config(Map.ofEntries( .config(Map.ofEntries(
@ -165,9 +168,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
EMAIL_ALIAS( EMAIL_ALIAS(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.EMAIL_ALIAS) .type(HsHostingAssetType.EMAIL_ALIAS)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .parentAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("xyz00-office") .identifier("xyz00-office")
.caption("some fake EMail-Alias") .caption("some fake EMail-Alias")
.config(Map.ofEntries( .config(Map.ofEntries(
@ -189,7 +192,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
DOMAIN_SETUP( DOMAIN_SETUP(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_SETUP) .type(HsHostingAssetType.DOMAIN_SETUP)
.identifier("example.org") .identifier("example.org")
.caption("some fake Domain-Setup") .caption("some fake Domain-Setup")
@ -207,7 +210,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
DOMAIN_DNS_SETUP( DOMAIN_DNS_SETUP(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_DNS_SETUP) .type(HsHostingAssetType.DOMAIN_DNS_SETUP)
.identifier("example.org") .identifier("example.org")
.caption("some fake Domain-DNS-Setup") .caption("some fake Domain-DNS-Setup")
@ -250,7 +253,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
DOMAIN_HTTP_SETUP( DOMAIN_HTTP_SETUP(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_HTTP_SETUP) .type(HsHostingAssetType.DOMAIN_HTTP_SETUP)
.identifier("example.org|HTTP") .identifier("example.org|HTTP")
.caption("some fake Domain-HTTP-Setup") .caption("some fake Domain-HTTP-Setup")
@ -303,7 +306,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
DOMAIN_SMTP_SETUP( DOMAIN_SMTP_SETUP(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_SMTP_SETUP) .type(HsHostingAssetType.DOMAIN_SMTP_SETUP)
.identifier("example.org|SMTP") .identifier("example.org|SMTP")
.caption("some fake Domain-SMTP-Setup") .caption("some fake Domain-SMTP-Setup")
@ -321,7 +324,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
DOMAIN_MBOX_SETUP( DOMAIN_MBOX_SETUP(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.DOMAIN_MBOX_SETUP) .type(HsHostingAssetType.DOMAIN_MBOX_SETUP)
.identifier("example.org|MBOX") .identifier("example.org|MBOX")
.caption("some fake Domain-MBOX-Setup") .caption("some fake Domain-MBOX-Setup")
@ -339,9 +342,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
EMAIL_ADDRESS( EMAIL_ADDRESS(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.EMAIL_ADDRESS) .type(HsHostingAssetType.EMAIL_ADDRESS)
.parentAsset(HsHostingAssetEntity.builder() .parentAsset(HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.DOMAIN_MBOX_SETUP) .type(HsHostingAssetType.DOMAIN_MBOX_SETUP)
.identifier("example.org|MBOX") .identifier("example.org|MBOX")
.caption("some fake Domain-MBOX-Setup") .caption("some fake Domain-MBOX-Setup")
@ -367,9 +370,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
MARIADB_INSTANCE( MARIADB_INSTANCE(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MARIADB_INSTANCE) .type(HsHostingAssetType.MARIADB_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET) .parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|MariaDB.default") .identifier("vm1234|MariaDB.default")
.caption("some fake MariaDB instance") .caption("some fake MariaDB instance")
.build()), .build()),
@ -386,7 +389,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
MARIADB_USER( MARIADB_USER(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MARIADB_USER) .type(HsHostingAssetType.MARIADB_USER)
.identifier("xyz00_temp") .identifier("xyz00_temp")
.caption("some fake MariaDB user") .caption("some fake MariaDB user")
@ -404,7 +407,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
MARIADB_DATABASE( MARIADB_DATABASE(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.MARIADB_DATABASE) .type(HsHostingAssetType.MARIADB_DATABASE)
.identifier("xyz00_temp") .identifier("xyz00_temp")
.caption("some fake MariaDB database") .caption("some fake MariaDB database")
@ -429,9 +432,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
PGSQL_INSTANCE( PGSQL_INSTANCE(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.PGSQL_INSTANCE) .type(HsHostingAssetType.PGSQL_INSTANCE)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET) .parentAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("vm1234|PgSql.default") .identifier("vm1234|PgSql.default")
.caption("some fake PgSql instance") .caption("some fake PgSql instance")
.build()), .build()),
@ -448,7 +451,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
PGSQL_USER( PGSQL_USER(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.PGSQL_USER) .type(HsHostingAssetType.PGSQL_USER)
.identifier("xyz00_temp") .identifier("xyz00_temp")
.caption("some fake PgSql user") .caption("some fake PgSql user")
@ -466,7 +469,7 @@ public class HsHostingAssetControllerRestTest {
"""), """),
PGSQL_DATABASE( PGSQL_DATABASE(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.PGSQL_DATABASE) .type(HsHostingAssetType.PGSQL_DATABASE)
.identifier("xyz00_temp") .identifier("xyz00_temp")
.caption("some fake PgSql database") .caption("some fake PgSql database")
@ -491,9 +494,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
IPV4_NUMBER( IPV4_NUMBER(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.IPV4_NUMBER) .type(HsHostingAssetType.IPV4_NUMBER)
.assignedToAsset(TEST_MANAGED_SERVER_HOSTING_ASSET) .assignedToAsset(MANAGED_SERVER_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("11.12.13.14") .identifier("11.12.13.14")
.caption("some fake IPv4 number") .caption("some fake IPv4 number")
.build()), .build()),
@ -510,9 +513,9 @@ public class HsHostingAssetControllerRestTest {
"""), """),
IPV6_NUMBER( IPV6_NUMBER(
List.of( List.of(
HsHostingAssetEntity.builder() HsHostingAssetRbacEntity.builder()
.type(HsHostingAssetType.IPV6_NUMBER) .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") .identifier("2001:db8:3333:4444:5555:6666:7777:8888")
.caption("some fake IPv6 number") .caption("some fake IPv6 number")
.build()), .build()),
@ -529,13 +532,13 @@ public class HsHostingAssetControllerRestTest {
"""); """);
final HsHostingAssetType assetType; final HsHostingAssetType assetType;
final List<HsHostingAssetEntity> givenHostingAssetsOfType; final List<HsHostingAssetRbacEntity> givenHostingAssetsOfType;
final String expectedResponse; final String expectedResponse;
final JsonNode expectedResponseJson; final JsonNode expectedResponseJson;
@SneakyThrows @SneakyThrows
ListTestCases( ListTestCases(
final List<HsHostingAssetEntity> givenHostingAssetsOfType, final List<HsHostingAssetRbacEntity> givenHostingAssetsOfType,
final String expectedResponse) { final String expectedResponse) {
this.assetType = HsHostingAssetType.valueOf(name()); this.assetType = HsHostingAssetType.valueOf(name());
this.givenHostingAssetsOfType = givenHostingAssetsOfType; this.givenHostingAssetsOfType = givenHostingAssetsOfType;
@ -561,7 +564,7 @@ public class HsHostingAssetControllerRestTest {
@EnumSource(HsHostingAssetControllerRestTest.ListTestCases.class) @EnumSource(HsHostingAssetControllerRestTest.ListTestCases.class)
void shouldListAssets(final HsHostingAssetControllerRestTest.ListTestCases testCase) throws Exception { void shouldListAssets(final HsHostingAssetControllerRestTest.ListTestCases testCase) throws Exception {
// given // given
when(hostingAssetRepo.findAllByCriteria(null, null, testCase.assetType)) when(rbacAssetRepo.findAllByCriteria(null, null, testCase.assetType))
.thenReturn(testCase.givenHostingAssetsOfType); .thenReturn(testCase.givenHostingAssetsOfType);
// when // when

View File

@ -15,7 +15,7 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Stream; 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.entry;
import static net.hostsharing.hsadminng.mapper.PatchMap.patchMap; import static net.hostsharing.hsadminng.mapper.PatchMap.patchMap;
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
@ -27,7 +27,7 @@ import static org.mockito.Mockito.lenient;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase< class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
HsHostingAssetPatchResource, HsHostingAssetPatchResource,
HsHostingAssetEntity HsHostingAssetRbacEntity
> { > {
private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID(); private static final UUID INITIAL_BOOKING_ITEM_UUID = UUID.randomUUID();
@ -60,17 +60,17 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
@BeforeEach @BeforeEach
void initMocks() { void initMocks() {
lenient().when(em.getReference(eq(HsHostingAssetEntity.class), any())).thenAnswer(invocation -> lenient().when(em.getReference(eq(HsHostingAssetRbacEntity.class), any())).thenAnswer(invocation ->
HsHostingAssetEntity.builder().uuid(invocation.getArgument(1)).build()); HsHostingAssetRbacEntity.builder().uuid(invocation.getArgument(1)).build());
lenient().when(em.getReference(eq(HsOfficeContactRealEntity.class), any())).thenAnswer(invocation -> lenient().when(em.getReference(eq(HsOfficeContactRealEntity.class), any())).thenAnswer(invocation ->
HsOfficeContactRealEntity.builder().uuid(invocation.getArgument(1)).build()); HsOfficeContactRealEntity.builder().uuid(invocation.getArgument(1)).build());
} }
@Override @Override
protected HsHostingAssetEntity newInitialEntity() { protected HsHostingAssetRbacEntity newInitialEntity() {
final var entity = new HsHostingAssetEntity(); final var entity = new HsHostingAssetRbacEntity();
entity.setUuid(INITIAL_BOOKING_ITEM_UUID); 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.getConfig().putAll(KeyValueMap.from(INITIAL_CONFIG));
entity.setCaption(INITIAL_CAPTION); entity.setCaption(INITIAL_CAPTION);
entity.setAlarmContact(givenInitialContact); entity.setAlarmContact(givenInitialContact);
@ -83,7 +83,7 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
} }
@Override @Override
protected HsHostingAssetEntityPatcher createPatcher(final HsHostingAssetEntity server) { protected HsHostingAssetEntityPatcher createPatcher(final HsHostingAssetRbacEntity server) {
return new HsHostingAssetEntityPatcher(em, server); return new HsHostingAssetEntityPatcher(em, server);
} }
@ -94,19 +94,19 @@ class HsHostingAssetEntityPatcherUnitTest extends PatchUnitTestBase<
"caption", "caption",
HsHostingAssetPatchResource::setCaption, HsHostingAssetPatchResource::setCaption,
PATCHED_CAPTION, PATCHED_CAPTION,
HsHostingAssetEntity::setCaption), HsHostingAssetRbacEntity::setCaption),
new SimpleProperty<>( new SimpleProperty<>(
"config", "config",
HsHostingAssetPatchResource::setConfig, HsHostingAssetPatchResource::setConfig,
PATCH_CONFIG, PATCH_CONFIG,
HsHostingAssetEntity::putConfig, HsHostingAssetRbacEntity::putConfig,
PATCHED_CONFIG) PATCHED_CONFIG)
.notNullable(), .notNullable(),
new JsonNullableProperty<>( new JsonNullableProperty<>(
"alarmContact", "alarmContact",
HsHostingAssetPatchResource::setAlarmContactUuid, HsHostingAssetPatchResource::setAlarmContactUuid,
PATCHED_CONTACT_UUID, PATCHED_CONTACT_UUID,
HsHostingAssetEntity::setAlarmContact, HsHostingAssetRbacEntity::setAlarmContact,
newContact(PATCHED_CONTACT_UUID)) newContact(PATCHED_CONTACT_UUID))
); );
} }

View File

@ -5,13 +5,13 @@ import org.junit.jupiter.api.Test;
import java.util.Map; import java.util.Map;
import static java.util.Map.entry; 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; import static org.assertj.core.api.Assertions.assertThat;
class HsHostingAssetEntityUnitTest { class HsHostingAssetEntityUnitTest {
final HsHostingAssetEntity givenParentAsset = HsHostingAssetEntity.builder() final HsHostingAssetRealEntity givenParentAsset = HsHostingAssetRealEntity.builder()
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM) .bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsHostingAssetType.MANAGED_SERVER) .type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234") .identifier("vm1234")
.caption("some managed asset") .caption("some managed asset")
@ -20,8 +20,8 @@ class HsHostingAssetEntityUnitTest {
entry("SSD-storage", 512), entry("SSD-storage", 512),
entry("HDD-storage", 2048))) entry("HDD-storage", 2048)))
.build(); .build();
final HsHostingAssetEntity givenWebspace = HsHostingAssetEntity.builder() final HsHostingAssetRealEntity givenWebspace = HsHostingAssetRealEntity.builder()
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM) .bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.type(HsHostingAssetType.MANAGED_WEBSPACE) .type(HsHostingAssetType.MANAGED_WEBSPACE)
.parentAsset(givenParentAsset) .parentAsset(givenParentAsset)
.identifier("xyz00") .identifier("xyz00")
@ -31,7 +31,7 @@ class HsHostingAssetEntityUnitTest {
entry("SSD-storage", 512), entry("SSD-storage", 512),
entry("HDD-storage", 2048))) entry("HDD-storage", 2048)))
.build(); .build();
final HsHostingAssetEntity givenUnixUser = HsHostingAssetEntity.builder() final HsHostingAssetRealEntity givenUnixUser = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.UNIX_USER) .type(HsHostingAssetType.UNIX_USER)
.parentAsset(givenWebspace) .parentAsset(givenWebspace)
.identifier("xyz00-web") .identifier("xyz00-web")
@ -42,7 +42,7 @@ class HsHostingAssetEntityUnitTest {
entry("HDD-soft-quota", 256), entry("HDD-soft-quota", 256),
entry("HDD-hard-quota", 512))) entry("HDD-hard-quota", 512)))
.build(); .build();
final HsHostingAssetEntity givenDomainHttpSetup = HsHostingAssetEntity.builder() final HsHostingAssetRealEntity givenDomainHttpSetup = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.DOMAIN_HTTP_SETUP) .type(HsHostingAssetType.DOMAIN_HTTP_SETUP)
.parentAsset(givenWebspace) .parentAsset(givenWebspace)
.identifier("example.org") .identifier("example.org")
@ -58,13 +58,13 @@ class HsHostingAssetEntityUnitTest {
void toStringContainsAllPropertiesAndResourcesSortedByKey() { void toStringContainsAllPropertiesAndResourcesSortedByKey() {
assertThat(givenWebspace.toString()).isEqualToIgnoringWhitespace( 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( 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( 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 @Test

View File

@ -1,10 +1,10 @@
package net.hostsharing.hsadminng.hs.hosting.asset; package net.hostsharing.hsadminng.hs.hosting.asset;
import net.hostsharing.hsadminng.context.Context; import net.hostsharing.hsadminng.context.Context;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealEntity;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository; import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRealRepository;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemType; 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.rbacgrant.RawRbacGrantRepository;
import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RawRbacRoleRepository;
import net.hostsharing.hsadminng.mapper.Array; 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 net.hostsharing.hsadminng.rbac.test.JpaAttempt;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; 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.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
@ -42,13 +44,16 @@ import static org.assertj.core.api.Assertions.assertThat;
class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanup { class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanup {
@Autowired @Autowired
HsHostingAssetRepository assetRepo; HsHostingAssetRealRepository realAssetRepo;
@Autowired @Autowired
HsBookingItemRepository bookingItemRepo; HsHostingAssetRbacRepository rbacAssetRepo;
@Autowired @Autowired
HsBookingProjectRepository projectRepo; HsBookingItemRealRepository realBookingItemRepo;
@Autowired
HsBookingProjectRbacRepository projectRepo;
@Autowired @Autowired
RawRbacRoleRepository rawRoleRepo; RawRbacRoleRepository rawRoleRepo;
@ -71,34 +76,35 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
@Test @Test
public void testHostsharingAdmin_withoutAssumedRole_canCreateNewAsset() { public void testHostsharingAdmin_withoutAssumedRole_canCreateNewAsset() {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net"); // TODO.test: remove context(...) once all entities have real entities
final var count = assetRepo.count(); final var count = realAssetRepo.count();
final var givenManagedServer = givenHostingAsset("D-1000111 default project", MANAGED_SERVER); final var givenManagedServer = givenHostingAsset("D-1000111 default project", MANAGED_SERVER);
final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01"); final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01");
// when // when
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
final var newAsset = HsHostingAssetEntity.builder() final var newAsset = HsHostingAssetRbacEntity.builder()
.bookingItem(newWebspaceBookingItem) .bookingItem(newWebspaceBookingItem)
.parentAsset(givenManagedServer) .parentAsset(givenManagedServer)
.caption("some new managed webspace") .caption("some new managed webspace")
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.identifier("xyz90") .identifier("xyz90")
.build(); .build();
return toCleanup(assetRepo.save(newAsset)); return toCleanup(rbacAssetRepo.save(newAsset));
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetEntity::getUuid).isNotNull(); assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetRbacEntity::getUuid).isNotNull();
assertThatAssetIsPersisted(result.returnedValue()); assertThatAssetIsPersisted(result.returnedValue());
assertThat(result.returnedValue().isLoaded()).isFalse(); assertThat(result.returnedValue().isLoaded()).isFalse();
assertThat(assetRepo.count()).isEqualTo(count + 1); assertThat(realAssetRepo.count()).isEqualTo(count + 1);
} }
@Test @Test
public void createsAndGrantsRoles() { public void createsAndGrantsRoles() {
// given // given
// TODO.test: remove context(...) once all entities have real entities
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT"); 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 givenManagedServer = givenHostingAsset("D-1000111 default project", MANAGED_SERVER);
final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01"); final var newWebspaceBookingItem = newBookingItem(givenManagedServer.getBookingItem(), HsBookingItemType.MANAGED_WEBSPACE, "fir01");
@ -107,15 +113,16 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll()); final var initialGrantNames = distinctGrantDisplaysOf(rawGrantRepo.findAll());
// when // when
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
final var newAsset = HsHostingAssetEntity.builder() final var newAsset = HsHostingAssetRbacEntity.builder()
.bookingItem(newWebspaceBookingItem) .bookingItem(newWebspaceBookingItem)
.parentAsset(givenManagedServer) .parentAsset(givenManagedServer)
.type(HsHostingAssetType.MANAGED_WEBSPACE) .type(HsHostingAssetType.MANAGED_WEBSPACE)
.identifier("fir00") .identifier("fir00")
.caption("some new managed webspace") .caption("some new managed webspace")
.build(); .build();
return toCleanup(assetRepo.save(newAsset)); return toCleanup(rbacAssetRepo.save(newAsset));
}); });
// then // then
@ -163,18 +170,18 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when // when
context("person-SmithPeter@example.com"); context("person-SmithPeter@example.com");
final var result = attempt(em, () -> { final var result = attempt(em, () -> {
final var newAsset = HsHostingAssetEntity.builder() final var newAsset = HsHostingAssetRbacEntity.builder()
.type(DOMAIN_SETUP) .type(DOMAIN_SETUP)
.identifier("example.net") .identifier("example.net")
.caption("some new domain setup") .caption("some new domain setup")
.build(); .build();
return assetRepo.save(newAsset); return rbacAssetRepo.save(newAsset);
}); });
// then // then
// ... the domain setup was created and returned // ... the domain setup was created and returned
result.assertSuccessful(); result.assertSuccessful();
assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetEntity::getUuid).isNotNull(); assertThat(result.returnedValue()).isNotNull().extracting(HsHostingAssetRbacEntity::getUuid).isNotNull();
assertThat(result.returnedValue().isLoaded()).isFalse(); assertThat(result.returnedValue().isLoaded()).isFalse();
// ... the creating user can read the new domain setup // ... the creating user can read the new domain setup
@ -186,11 +193,11 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
assertThatAssetIsPersisted(result.returnedValue()); assertThatAssetIsPersisted(result.returnedValue());
} }
private void assertThatAssetIsPersisted(final HsHostingAssetEntity saved) { private void assertThatAssetIsPersisted(final HsHostingAssetRbacEntity saved) {
em.clear(); em.clear();
attempt(em, () -> { attempt(em, () -> {
final var found = assetRepo.findByUuid(saved.getUuid()); final var found = realAssetRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().map(HsHostingAssetEntity::toString).contains(saved.toString()); assertThat(found).isNotEmpty().map(HsHostingAsset::toString).contains(saved.toString());
}); });
} }
} }
@ -198,20 +205,21 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
@Nested @Nested
class FindAssets { class FindAssets {
@Test @ParameterizedTest
public void globalAdmin_withoutAssumedRole_canViewArbitraryAssetsOfAllDebitors() { @EnumSource(TestCase.class)
public void globalAdmin_withoutAssumedRole_canViewArbitraryAssetsOfAllDebitors(final TestCase testCase) {
// given // given
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
// when // when
final var result = assetRepo.findAllByCriteria(null, null, MANAGED_WEBSPACE); final var result = repoUnderTest(testCase).findAllByCriteria(null, null, MANAGED_WEBSPACE);
// then // then
exactlyTheseAssetsAreReturned( exactlyTheseAssetsAreReturned(
result, result,
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)", "HsHostingAsset(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)", "HsHostingAsset(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, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedWebspace)");
} }
@Test @Test
@ -222,33 +230,32 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
// when: // when:
final var result = assetRepo.findAllByCriteria(projectUuid, null, null); final var result = rbacAssetRepo.findAllByCriteria(projectUuid, null, null);
// then: // then:
exactlyTheseAssetsAreReturned( exactlyTheseAssetsAreReturned(
result, result,
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedWebspace)", "HsHostingAsset(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_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 @Test
public void managedServerAgent_canFindAssetsRelatedToManagedServer() { public void managedServerAgent_canFindAssetsRelatedToManagedServer() {
// given // given
context("superuser-alex@hostsharing.net"); final var parentAssetUuid = realAssetRepo.findByIdentifier("vm1012").stream()
final var parentAssetUuid = assetRepo.findByIdentifier("vm1012").stream()
.filter(ha -> ha.getType() == MANAGED_SERVER) .filter(ha -> ha.getType() == MANAGED_SERVER)
.findAny().orElseThrow().getUuid(); .findAny().orElseThrow().getUuid();
// when // when
context("superuser-alex@hostsharing.net", "hs_hosting_asset#vm1012:AGENT"); 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 // then
exactlyTheseAssetsAreReturned( exactlyTheseAssetsAreReturned(
result, result,
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedWebspace)", "HsHostingAsset(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)", "HsHostingAsset(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(PGSQL_INSTANCE, vm1012.Postgresql.default, some default Postgresql instance, MANAGED_SERVER:vm1012)");
} }
@Test @Test
@ -258,12 +265,12 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when // when
context("superuser-alex@hostsharing.net", "hs_hosting_asset#sec01:AGENT"); 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 // then
exactlyTheseAssetsAreReturned( exactlyTheseAssetsAreReturned(
result, 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 // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); 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().put("CPU", 2);
foundAsset.getConfig().remove("SSD-storage"); foundAsset.getConfig().remove("SSD-storage");
foundAsset.getConfig().put("HSD-storage", 2048); foundAsset.getConfig().put("HSD-storage", 2048);
return toCleanup(assetRepo.save(foundAsset)); return toCleanup(rbacAssetRepo.save(foundAsset));
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
jpaAttempt.transacted(() -> { jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net");
assertThatAssetActuallyInDatabase(result.returnedValue()); assertThatAssetActuallyInDatabase(result.returnedValue());
}).assertSuccessful(); }).assertSuccessful();
} }
private void assertThatAssetActuallyInDatabase(final HsHostingAssetEntity saved) { private void assertThatAssetActuallyInDatabase(final HsHostingAssetRbacEntity saved) {
final var found = assetRepo.findByUuid(saved.getUuid()); final var found = realAssetRepo.findByUuid(saved.getUuid());
assertThat(found).isNotEmpty().get().isNotSameAs(saved) 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 // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
assetRepo.deleteByUuid(givenAsset.getUuid()); rbacAssetRepo.deleteByUuid(givenAsset.getUuid());
}); });
// then // then
result.assertSuccessful(); result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null); return realAssetRepo.findByUuid(givenAsset.getUuid());
return assetRepo.findByUuid(givenAsset.getUuid());
}).assertSuccessful().returnedValue()).isEmpty(); }).assertSuccessful().returnedValue()).isEmpty();
} }
@Test @Test
public void relatedOwner_canDeleteTheirRelatedAsset() { public void relatedOwner_canDeleteTheirRelatedAsset() {
// given // given
context("superuser-alex@hostsharing.net", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT");
final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000"); final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000");
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_booking_project#D-1000111-D-1000111defaultproject:AGENT"); 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 // then
result.assertSuccessful(); result.assertSuccessful();
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context("superuser-fran@hostsharing.net", null); return realAssetRepo.findByUuid(givenAsset.getUuid());
return assetRepo.findByUuid(givenAsset.getUuid());
}).assertSuccessful().returnedValue()).isEmpty(); }).assertSuccessful().returnedValue()).isEmpty();
} }
@Test @Test
public void relatedAdmin_canNotDeleteTheirRelatedAsset() { public void relatedAdmin_canNotDeleteTheirRelatedAsset() {
// given // given
context("superuser-alex@hostsharing.net", null);
final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000"); final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000");
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("person-FirbySusan@example.com", "hs_hosting_asset#vm1000:ADMIN"); 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 // then
@ -364,15 +366,13 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
JpaSystemException.class, JpaSystemException.class,
"[403] Subject ", " is not allowed to delete hs_hosting_asset"); "[403] Subject ", " is not allowed to delete hs_hosting_asset");
assertThat(jpaAttempt.transacted(() -> { assertThat(jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); return realAssetRepo.findByUuid(givenAsset.getUuid());
return assetRepo.findByUuid(givenAsset.getUuid());
}).assertSuccessful().returnedValue()).isPresent(); // still there }).assertSuccessful().returnedValue()).isPresent(); // still there
} }
@Test @Test
public void deletingAnAssetAlsoDeletesRelatedRolesAndGrants() { public void deletingAnAssetAlsoDeletesRelatedRolesAndGrants() {
// given // given
context("superuser-alex@hostsharing.net");
final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll())); final var initialRoleNames = Array.from(distinctRoleNamesOf(rawRoleRepo.findAll()));
final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll())); final var initialGrantNames = Array.from(distinctGrantDisplaysOf(rawGrantRepo.findAll()));
final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000"); final var givenAsset = givenSomeTemporaryAsset("D-1000111 default project", "vm1000");
@ -380,7 +380,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
// when // when
final var result = jpaAttempt.transacted(() -> { final var result = jpaAttempt.transacted(() -> {
context("superuser-alex@hostsharing.net"); context("superuser-alex@hostsharing.net");
return assetRepo.deleteByUuid(givenAsset.getUuid()); return rbacAssetRepo.deleteByUuid(givenAsset.getUuid());
}); });
// then // then
@ -398,7 +398,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
select currentTask, targetTable, targetOp select currentTask, targetTable, targetOp
from tx_journal_v from tx_journal_v
where targettable = 'hs_hosting_asset'; where targettable = 'hs_hosting_asset';
"""); """);
// when // when
@SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList(); @SuppressWarnings("unchecked") final List<Object[]> customerLogEntries = query.getResultList();
@ -410,57 +410,89 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
"[creating hosting-asset test-data D-1000313 default project, hs_hosting_asset, INSERT]"); "[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(() -> { 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 givenBookingItem = givenBookingItem("D-1000111 default project", "test CloudServer");
final var newAsset = HsHostingAssetEntity.builder() final var newAsset = HsHostingAssetRealEntity.builder()
.bookingItem(givenBookingItem) .bookingItem(givenBookingItem)
.type(CLOUD_SERVER) .type(CLOUD_SERVER)
.identifier(identifier) .identifier(identifier)
.caption("some temp cloud asset") .caption(projectCaption)
.config(Map.ofEntries( .config(Map.ofEntries(
entry("CPU", 1), entry("CPU", 1),
entry("SSD-storage", 256))) entry("SSD-storage", 256)))
.build(); .build();
return toCleanup(assetRepo.save(newAsset)); return toCleanup(realAssetRepo.save(newAsset));
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
} }
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) { HsBookingItemRealEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
return bookingItemRepo.findByCaption(bookingItemCaption).stream() return realBookingItemRepo.findByCaption(bookingItemCaption).stream()
.filter(i -> i.getRelatedProject().getCaption().equals(projectCaption)) .filter(i -> i.getRelatedProject().getCaption().equals(projectCaption))
.findAny().orElseThrow(); .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() final var givenProject = projectRepo.findByCaption(projectCaption).stream()
.findAny().orElseThrow(); .findAny().orElseThrow();
return assetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream() return realAssetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream()
.findAny().orElseThrow(); .findAny().orElseThrow();
} }
HsBookingItemEntity newBookingItem( HsBookingItemRealEntity newBookingItem(
final HsBookingItemEntity parentBookingItem, final HsBookingItemRealEntity parentBookingItem,
final HsBookingItemType type, final HsBookingItemType type,
final String caption) { final String caption) {
final var newBookingItem = HsBookingItemEntity.builder() final var newBookingItem = HsBookingItemRealEntity.builder()
.parentItem(parentBookingItem) .parentItem(parentBookingItem)
.type(type) .type(type)
.caption(caption) .caption(caption)
.build(); .build();
return toCleanup(bookingItemRepo.save(newBookingItem)); return toCleanup(realBookingItemRepo.save(newBookingItem));
} }
void exactlyTheseAssetsAreReturned( void exactlyTheseAssetsAreReturned(
final List<HsHostingAssetEntity> actualResult, final List<? extends HsHostingAsset> actualResult,
final String... serverNames) { final String... serverNames) {
assertThat(actualResult) assertThat(actualResult)
.extracting(HsHostingAssetEntity::toString) .extracting(HsHostingAsset::toString)
.extracting(input -> input.replaceAll("\\s+", " ")) .extracting(input -> input.replaceAll("\\s+", " "))
.extracting(input -> input.replaceAll("\"", "")) .extracting(input -> input.replaceAll("\"", ""))
.extracting(input -> input.replaceAll("\" : ", "\": ")) .extracting(input -> input.replaceAll("\" : ", "\": "))
.containsExactlyInAnyOrder(serverNames); .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; 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.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 org.junit.jupiter.api.Test;
import java.util.Map; import java.util.Map;
import static java.util.Map.entry; 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.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -18,7 +19,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test @Test
void validatesProperties() { void validatesProperties() {
// given // given
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder() final var cloudServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(CLOUD_SERVER) .type(CLOUD_SERVER)
.identifier("vm1234") .identifier("vm1234")
.config(Map.ofEntries( .config(Map.ofEntries(
@ -40,10 +41,10 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test @Test
void validatesInvalidIdentifier() { void validatesInvalidIdentifier() {
// given // given
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder() final var cloudServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(CLOUD_SERVER) .type(CLOUD_SERVER)
.identifier("xyz99") .identifier("xyz99")
.bookingItem(TEST_CLOUD_SERVER_BOOKING_ITEM) .bookingItem(CLOUD_SERVER_BOOKING_ITEM_REAL_ENTITY)
.build(); .build();
final var validator = HostingAssetEntityValidatorRegistry.forType(cloudServerHostingAssetEntity.getType()); final var validator = HostingAssetEntityValidatorRegistry.forType(cloudServerHostingAssetEntity.getType());
@ -68,10 +69,10 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test @Test
void validatesBookingItemType() { void validatesBookingItemType() {
// given // given
final var mangedServerHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_SERVER) .type(MANAGED_SERVER)
.identifier("xyz00") .identifier("xyz00")
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build()) .bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.build(); .build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType()); final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());
@ -86,12 +87,12 @@ class HsCloudServerHostingAssetValidatorUnitTest {
@Test @Test
void rejectsInvalidReferencedEntities() { void rejectsInvalidReferencedEntities() {
// given // given
final var mangedServerHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedServerHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(CLOUD_SERVER) .type(CLOUD_SERVER)
.identifier("vm1234") .identifier("vm1234")
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build()) .bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_SERVER).build()) .parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_SERVER).build())
.assignedToAsset(HsHostingAssetEntity.builder().type(CLOUD_SERVER).build()) .assignedToAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.build(); .build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType()); final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

@ -1,20 +1,21 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators; 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.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.HsHostingAssetEntity.HsHostingAssetEntityBuilder; import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetRealEntity;
import net.hostsharing.hsadminng.mapper.Array; import net.hostsharing.hsadminng.mapper.Array;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jakarta.persistence.EntityManager;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import static java.util.Map.entry; 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_DNS_SETUP;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.DOMAIN_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_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_DATA;
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsDomainDnsSetupHostingAssetValidator.RR_RECORD_TYPE; 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 { class HsDomainDnsSetupHostingAssetValidatorUnitTest {
static final HsHostingAssetEntity validDomainSetupEntity = HsHostingAssetEntity.builder() static final HsHostingAssetRealEntity validDomainSetupEntity = HsHostingAssetRealEntity.builder()
.type(DOMAIN_SETUP) .type(DOMAIN_SETUP)
.identifier("example.org") .identifier("example.org")
.build(); .build();
static HsHostingAssetEntityBuilder validEntityBuilder() { private EntityManager em;
return HsHostingAssetEntity.builder()
static HsHostingAssetRbacEntity.HsHostingAssetRbacEntityBuilder<?, ?> validEntityBuilder() {
return HsHostingAssetRbacEntity.builder()
.type(DOMAIN_DNS_SETUP) .type(DOMAIN_DNS_SETUP)
.parentAsset(validDomainSetupEntity) .parentAsset(validDomainSetupEntity)
.assignedToAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .assignedToAsset(MANAGED_WEBSPACE_HOSTING_ASSET_REAL_TEST_ENTITY)
.identifier("example.org|DNS") .identifier("example.org|DNS")
.config(Map.ofEntries( .config(Map.ofEntries(
entry("TTL", 21600), entry("TTL", 21600),
@ -139,9 +142,9 @@ class HsDomainDnsSetupHostingAssetValidatorUnitTest {
void rejectsInvalidReferencedEntities() { void rejectsInvalidReferencedEntities() {
// given // given
final var mangedServerHostingAssetEntity = validEntityBuilder() final var mangedServerHostingAssetEntity = validEntityBuilder()
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build()) .bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.CLOUD_SERVER).build())
.parentAsset(null) .parentAsset(null)
.assignedToAsset(HsHostingAssetEntity.builder().type(DOMAIN_SETUP).build()) .assignedToAsset(HsHostingAssetRealEntity.builder().type(DOMAIN_SETUP).build())
.build(); .build();
final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType()); final var validator = HostingAssetEntityValidatorRegistry.forType(mangedServerHostingAssetEntity.getType());

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,15 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators; 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.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.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import org.junit.jupiter.api.Test; 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.Map;
import java.util.stream.Stream; 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.CLOUD_SERVER;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
import static org.assertj.core.api.Assertions.assertThat; 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 { class HsManagedWebspaceHostingAssetValidatorUnitTest {
final HsBookingItemEntity managedServerBookingItem = HsBookingItemEntity.builder() final HsBookingItemRealEntity managedServerBookingItem = HsBookingItemRealEntity.builder()
.project(TEST_PROJECT) .project(PROJECT_TEST_ENTITY)
.type(HsBookingItemType.MANAGED_SERVER) .type(HsBookingItemType.MANAGED_SERVER)
.caption("Test Managed-Server") .caption("Test Managed-Server")
.resources(Map.ofEntries( .resources(Map.ofEntries(
@ -30,12 +36,12 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
entry("SLA-EMail", true) entry("SLA-EMail", true)
)) ))
.build(); .build();
final HsBookingItemEntity cloudServerBookingItem = managedServerBookingItem.toBuilder() final HsBookingItemRealEntity cloudServerBookingItem = managedServerBookingItem.toBuilder()
.type(HsBookingItemType.CLOUD_SERVER) .type(HsBookingItemType.CLOUD_SERVER)
.caption("Test Cloud-Server") .caption("Test Cloud-Server")
.build(); .build();
final HsHostingAssetEntity mangedServerAssetEntity = HsHostingAssetEntity.builder() final HsHostingAssetRealEntity mangedServerAssetEntity = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.MANAGED_SERVER) .type(HsHostingAssetType.MANAGED_SERVER)
.bookingItem(managedServerBookingItem) .bookingItem(managedServerBookingItem)
.identifier("vm1234") .identifier("vm1234")
@ -45,7 +51,7 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
entry("monit_max_ram_usage", 90) entry("monit_max_ram_usage", 90)
)) ))
.build(); .build();
final HsHostingAssetEntity cloudServerAssetEntity = HsHostingAssetEntity.builder() final HsHostingAssetRealEntity cloudServerAssetEntity = HsHostingAssetRealEntity.builder()
.type(HsHostingAssetType.CLOUD_SERVER) .type(HsHostingAssetType.CLOUD_SERVER)
.bookingItem(cloudServerBookingItem) .bookingItem(cloudServerBookingItem)
.identifier("vm1234") .identifier("vm1234")
@ -60,9 +66,9 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void acceptsAlienIdentifierPrefixForPreExistingEntity() { void acceptsAlienIdentifierPrefixForPreExistingEntity() {
// given // given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE); final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder() .bookingItem(HsBookingItemRealEntity.builder()
.type(HsBookingItemType.MANAGED_WEBSPACE) .type(HsBookingItemType.MANAGED_WEBSPACE)
.resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250))) .resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250)))
.build()) .build())
@ -70,9 +76,11 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
.identifier("xyz00") .identifier("xyz00")
.isLoaded(true) .isLoaded(true)
.build(); .build();
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when // when
final var result = validator.validateContext(mangedWebspaceHostingAssetEntity); final var result = HsEntityValidator.doWithEntityManager(em, () ->
validator.validateContext(mangedWebspaceHostingAssetEntity));
// then // then
assertThat(result).isEmpty(); assertThat(result).isEmpty();
@ -82,9 +90,9 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void validatesIdentifierAndReferencedEntities() { void validatesIdentifierAndReferencedEntities() {
// given // given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE); final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build()) .bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
.parentAsset(mangedServerAssetEntity) .parentAsset(mangedServerAssetEntity)
.identifier("xyz00") .identifier("xyz00")
.build(); .build();
@ -100,9 +108,9 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void validatesUnknownProperties() { void validatesUnknownProperties() {
// given // given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE); final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build()) .bookingItem(HsBookingItemRealEntity.builder().type(HsBookingItemType.MANAGED_WEBSPACE).build())
.parentAsset(mangedServerAssetEntity) .parentAsset(mangedServerAssetEntity)
.identifier("abc00") .identifier("abc00")
.config(Map.ofEntries( .config(Map.ofEntries(
@ -121,23 +129,25 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void validatesValidEntity() { void validatesValidEntity() {
// given // given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE); final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder() .bookingItem(HsBookingItemRealEntity.builder()
.type(HsBookingItemType.MANAGED_WEBSPACE) .type(HsBookingItemType.MANAGED_WEBSPACE)
.project(TEST_PROJECT) .project(PROJECT_TEST_ENTITY)
.caption("some ManagedWebspace") .caption("some ManagedWebspace")
.resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250))) .resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250)))
.build()) .build())
.parentAsset(mangedServerAssetEntity) .parentAsset(mangedServerAssetEntity)
.identifier("abc00") .identifier("abc00")
.build(); .build();
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when // when
final var result = Stream.concat( final var result = HsEntityValidator.doWithEntityManager(em, () ->
Stream.concat(
validator.validateEntity(mangedWebspaceHostingAssetEntity).stream(), validator.validateEntity(mangedWebspaceHostingAssetEntity).stream(),
validator.validateContext(mangedWebspaceHostingAssetEntity).stream()) validator.validateContext(mangedWebspaceHostingAssetEntity).stream())
.toList(); .toList());
// then // then
assertThat(result).isEmpty(); assertThat(result).isEmpty();
@ -147,15 +157,15 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
void rejectsInvalidEntityReferences() { void rejectsInvalidEntityReferences() {
// given // given
final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE); final var validator = HostingAssetEntityValidatorRegistry.forType(MANAGED_WEBSPACE);
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder() final var mangedWebspaceHostingAssetEntity = HsHostingAssetRbacEntity.builder()
.type(MANAGED_WEBSPACE) .type(MANAGED_WEBSPACE)
.bookingItem(HsBookingItemEntity.builder() .bookingItem(HsBookingItemRealEntity.builder()
.type(HsBookingItemType.MANAGED_SERVER) .type(HsBookingItemType.MANAGED_SERVER)
.caption("some ManagedServer") .caption("some ManagedServer")
.resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250))) .resources(Map.ofEntries(entry("SSD", 25), entry("Traffic", 250)))
.build()) .build())
.parentAsset(cloudServerAssetEntity) .parentAsset(cloudServerAssetEntity)
.assignedToAsset(HsHostingAssetEntity.builder().type(CLOUD_SERVER).build()) .assignedToAsset(HsHostingAssetRealEntity.builder().type(CLOUD_SERVER).build())
.identifier("abc00") .identifier("abc00")
.build(); .build();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,8 +1,11 @@
package net.hostsharing.hsadminng.hs.hosting.asset.validators; package net.hostsharing.hsadminng.hs.hosting.asset.validators;
import net.hostsharing.hsadminng.hash.HashGenerator; 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.hosting.asset.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@ -15,8 +18,8 @@ import java.util.HashMap;
import java.util.stream.Stream; import java.util.stream.Stream;
import static java.util.Map.ofEntries; 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.booking.item.TestHsBookingItem.TEST_MANAGED_WEBSPACE_BOOKING_ITEM; 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.MANAGED_WEBSPACE;
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER; import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.UNIX_USER;
import static net.hostsharing.hsadminng.mapper.PatchMap.entry; import static net.hostsharing.hsadminng.mapper.PatchMap.entry;
@ -27,21 +30,27 @@ import static org.mockito.Mockito.mock;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class HsUnixUserHostingAssetValidatorUnitTest { 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) .type(HsHostingAssetType.MANAGED_SERVER)
.identifier("vm1234") .identifier("vm1234")
.caption("some managed server") .caption("some managed server")
.bookingItem(TEST_MANAGED_SERVER_BOOKING_ITEM) .bookingItem(MANAGED_SERVER_BOOKING_ITEM_REAL_ENTITY)
.build(); .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) .type(MANAGED_WEBSPACE)
.bookingItem(TEST_MANAGED_WEBSPACE_BOOKING_ITEM) .bookingItem(MANAGED_WEBSPACE_BOOKING_ITEM_REAL_ENTITY)
.parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET) .parentAsset(TEST_MANAGED_SERVER_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00") .identifier("abc00")
.build(); .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) .type(UNIX_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00-temp") .identifier("abc00-temp")
.caption("some valid test UnixUser") .caption("some valid test UnixUser")
.config(new HashMap<>(ofEntries( .config(new HashMap<>(ofEntries(
@ -89,12 +98,13 @@ class HsUnixUserHostingAssetValidatorUnitTest {
// given // given
final var unixUserHostingAsset = GIVEN_VALID_UNIX_USER_HOSTING_ASSET; final var unixUserHostingAsset = GIVEN_VALID_UNIX_USER_HOSTING_ASSET;
final var validator = HostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType()); final var validator = HostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType());
final var em = EntityManagerMock.createEntityManagerMockWithAssetQueryFake(null);
// when // when
final var result = Stream.concat( final var result = HsEntityValidator.doWithEntityManager(em, () -> Stream.concat(
validator.validateEntity(unixUserHostingAsset).stream(), validator.validateEntity(unixUserHostingAsset).stream(),
validator.validateContext(unixUserHostingAsset).stream() validator.validateContext(unixUserHostingAsset).stream()
).toList(); ).toList());
// then // then
assertThat(result).isEmpty(); assertThat(result).isEmpty();
@ -103,9 +113,9 @@ class HsUnixUserHostingAssetValidatorUnitTest {
@Test @Test
void validatesUnixUserProperties() { void validatesUnixUserProperties() {
// given // given
final var unixUserHostingAsset = HsHostingAssetEntity.builder() final var unixUserHostingAsset = HsHostingAssetRbacEntity.builder()
.type(UNIX_USER) .type(UNIX_USER)
.parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET) .parentAsset(TEST_MANAGED_WEBSPACE_HOSTING_ASSET_REAL_ENTITY)
.identifier("abc00-temp") .identifier("abc00-temp")
.caption("some test UnixUser with invalid properties") .caption("some test UnixUser with invalid properties")
.config(ofEntries( .config(ofEntries(
@ -140,9 +150,9 @@ class HsUnixUserHostingAssetValidatorUnitTest {
@Test @Test
void validatesInvalidIdentifier() { void validatesInvalidIdentifier() {
// given // given
final var unixUserHostingAsset = HsHostingAssetEntity.builder() final var unixUserHostingAsset = HsHostingAssetRbacEntity.builder()
.type(UNIX_USER) .type(UNIX_USER)
.parentAsset(HsHostingAssetEntity.builder().type(MANAGED_WEBSPACE).identifier("abc00").build()) .parentAsset(HsHostingAssetRealEntity.builder().type(MANAGED_WEBSPACE).identifier("abc00").build())
.identifier("xyz99-temp") .identifier("xyz99-temp")
.build(); .build();
final var validator = HostingAssetEntityValidatorRegistry.forType(unixUserHostingAsset.getType()); 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;
import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm; import net.hostsharing.hsadminng.hash.HashGenerator.Algorithm;
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity; 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.HsBookingItemType;
import net.hostsharing.hsadminng.hs.booking.item.validators.HsBookingItemEntityValidatorRegistry; 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.HsHostingAssetType;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor; import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntitySaveProcessor;
import net.hostsharing.hsadminng.hs.hosting.asset.validators.HostingAssetEntityValidatorRegistry; 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) {} 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, HsBookingProjectRealEntity> bookingProjects = new WriteOnceMap<>();
static Map<Integer, HsBookingItemEntity> bookingItems = new WriteOnceMap<>(); static Map<Integer, HsBookingItem> bookingItems = new WriteOnceMap<>();
static Map<Integer, Hive> hives = new WriteOnceMap<>(); static Map<Integer, Hive> hives = new WriteOnceMap<>();
static Map<Integer, HsHostingAssetRealEntity> ipNumberAssets = new WriteOnceMap<>(); static Map<Integer, HsHostingAssetRealEntity> ipNumberAssets = new WriteOnceMap<>();
@ -157,7 +159,7 @@ public class ImportHostingAssets extends ImportOfficeData {
@Order(11010) @Order(11010)
void createBookingProjects() { void createBookingProjects() {
debitors.forEach((id, debitor) -> { debitors.forEach((id, debitor) -> {
bookingProjects.put(id, HsBookingProjectEntity.builder() bookingProjects.put(id, HsBookingProjectRealEntity.builder()
.caption(debitor.getDefaultPrefix() + " default project") .caption(debitor.getDefaultPrefix() + " default project")
.debitor(em.find(HsBookingDebitorEntity.class, debitor.getUuid())) .debitor(em.find(HsBookingDebitorEntity.class, debitor.getUuid()))
.build()); .build());
@ -182,11 +184,11 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(5, ipNumberAssets)).isEqualToIgnoringWhitespace(""" assertThat(firstOfEach(5, ipNumberAssets)).isEqualToIgnoringWhitespace("""
{ {
363=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.34), 363=HsHostingAsset(IPV4_NUMBER, 83.223.95.34),
381=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.52), 381=HsHostingAsset(IPV4_NUMBER, 83.223.95.52),
401=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.72), 401=HsHostingAsset(IPV4_NUMBER, 83.223.95.72),
402=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.73), 402=HsHostingAsset(IPV4_NUMBER, 83.223.95.73),
433=HsHostingAssetRealEntity(IPV4_NUMBER, 83.223.95.104) 433=HsHostingAsset(IPV4_NUMBER, 83.223.95.104)
} }
"""); """);
} }
@ -251,15 +253,15 @@ public class ImportHostingAssets extends ImportOfficeData {
"""); """);
assertThat(firstOfEach(9, packetAssets)).isEqualToIgnoringWhitespace(""" assertThat(firstOfEach(9, packetAssets)).isEqualToIgnoringWhitespace("""
{ {
10630=HsHostingAssetRealEntity(MANAGED_WEBSPACE, hsh00, HA hsh00, MANAGED_SERVER:vm1050, D-1000000:hsh default project:BI hsh00), 10630=HsHostingAsset(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), 10968=HsHostingAsset(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), 10978=HsHostingAsset(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), 11061=HsHostingAsset(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), 11094=HsHostingAsset(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), 11111=HsHostingAsset(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), 11112=HsHostingAsset(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), 11447=HsHostingAsset(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) 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)) assertThat(firstOfEach(7, packetAssets))
.isEqualToIgnoringWhitespace(""" .isEqualToIgnoringWhitespace("""
{ {
10630=HsHostingAssetRealEntity(MANAGED_WEBSPACE, hsh00, HA hsh00, MANAGED_SERVER:vm1050, D-1000000:hsh default project:BI hsh00), 10630=HsHostingAsset(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), 10968=HsHostingAsset(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), 10978=HsHostingAsset(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), 11061=HsHostingAsset(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), 11094=HsHostingAsset(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), 11111=HsHostingAsset(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) 11112=HsHostingAsset(MANAGED_WEBSPACE, mim00, HA mim00, MANAGED_SERVER:vm1068, D-1000300:mim default project:BI mim00)
} }
"""); """);
assertThat(firstOfEachType( assertThat(firstOfEachType(
@ -331,21 +333,21 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(15, unixUserAssets)).isEqualToIgnoringWhitespace(""" 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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=HsHostingAssetRealEntity(UNIX_USER, xyz68, Monitoring h68, MANAGED_WEBSPACE:xyz68, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102141}), 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=HsHostingAssetRealEntity(UNIX_USER, mim00, Michael Mellis, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102147}), 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=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}), 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=HsHostingAssetRealEntity(UNIX_USER, mim00-mail, Mailbox, MANAGED_WEBSPACE:mim00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 102160}), 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=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}), 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=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}), 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=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}), 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=HsHostingAssetRealEntity(UNIX_USER, dph00, Reinhard Wiese, MANAGED_WEBSPACE:dph00, {"SSD hard quota": 0, "SSD soft quota": 0, "locked": false, "shell": "/bin/bash", "userid": 110593}), 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=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}) 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(""" assertThat(firstOfEach(15, emailAliasAssets)).isEqualToIgnoringWhitespace("""
{ {
2403=HsHostingAssetRealEntity(EMAIL_ALIAS, lug00, lug00, MANAGED_WEBSPACE:lug00, {"target": [ "michael.mellis@example.com" ]}), 2403=HsHostingAsset(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" ]}), 2405=HsHostingAsset(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" ]}), 2429=HsHostingAsset(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" ]}), 2431=HsHostingAsset(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" ]}), 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=HsHostingAssetRealEntity(EMAIL_ALIAS, mim00-hhfx-l, mim00-hhfx-l, MANAGED_WEBSPACE:mim00, {"target": [ ":include:/home/pacs/mim00/etc/hhfx.list" ]}), 2451=HsHostingAsset(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" ]}), 2454=HsHostingAsset(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" ]}), 2455=HsHostingAsset(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" ]}) 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(""" assertThat(firstOfEach(8, dbInstanceAssets)).isEqualToIgnoringWhitespace("""
{ {
0=HsHostingAssetRealEntity(PGSQL_INSTANCE, vm1061|PgSql.default, vm1061-PostgreSQL default instance, MANAGED_SERVER:vm1061), 0=HsHostingAsset(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), 1=HsHostingAsset(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), 2=HsHostingAsset(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), 3=HsHostingAsset(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), 4=HsHostingAsset(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), 5=HsHostingAsset(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), 6=HsHostingAsset(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) 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(""" 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="}), 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=HsHostingAssetRealEntity(MARIADB_USER, MAU|hsh00, hsh00, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*59067A36BA197AD0A47D74909296C5B002A0FB9F"}), 1858=HsHostingAsset(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="}), 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=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="}), 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=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="}), 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=HsHostingAssetRealEntity(MARIADB_USER, MAU|hsh00_mantis, hsh00_mantis, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*EA4C0889A22AAE66BBEBC88161E8CF862D73B44F"}), 4908=HsHostingAsset(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"}), 4909=HsHostingAsset(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="}), 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=HsHostingAssetRealEntity(MARIADB_USER, MAU|hsh00_phpMyAdmin, hsh00_phpMyAdmin, MANAGED_WEBSPACE:hsh00, MARIADB_INSTANCE:vm1050|MariaDB.default, { "password": "*3188720B1889EF5447C722629765F296F40257C2"}), 4932=HsHostingAsset(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"}) 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(""" assertThat(firstOfEach(10, dbAssets)).isEqualToIgnoringWhitespace("""
{ {
1077=HsHostingAssetRealEntity(PGSQL_DATABASE, PGD|hsh00_vorstand, hsh00_vorstand, PGSQL_USER:PGU|hsh00_vorstand, {"encoding": "LATIN1"}), 1077=HsHostingAsset(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"}), 1786=HsHostingAsset(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"}), 1805=HsHostingAsset(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"}), 1858=HsHostingAsset(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"}), 1860=HsHostingAsset(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"}), 4908=HsHostingAsset(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"}), 4931=HsHostingAsset(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"}), 4932=HsHostingAsset(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"}), 4941=HsHostingAsset(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"}) 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(""" assertThat(firstOfEach(12, domainSetupAssets)).isEqualToIgnoringWhitespace("""
{ {
4531=HsHostingAssetRealEntity(DOMAIN_SETUP, l-u-g.org, l-u-g.org), 4531=HsHostingAsset(DOMAIN_SETUP, l-u-g.org, l-u-g.org),
4532=HsHostingAssetRealEntity(DOMAIN_SETUP, linuxfanboysngirls.de, linuxfanboysngirls.de), 4532=HsHostingAsset(DOMAIN_SETUP, linuxfanboysngirls.de, linuxfanboysngirls.de),
4534=HsHostingAssetRealEntity(DOMAIN_SETUP, lug-mars.de, lug-mars.de), 4534=HsHostingAsset(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), 4581=HsHostingAsset(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), 4587=HsHostingAsset(DOMAIN_SETUP, mellis.de, mellis.de),
4589=HsHostingAssetRealEntity(DOMAIN_SETUP, ist-im-netz.de, ist-im-netz.de), 4589=HsHostingAsset(DOMAIN_SETUP, ist-im-netz.de, ist-im-netz.de),
4600=HsHostingAssetRealEntity(DOMAIN_SETUP, waera.de, waera.de), 4600=HsHostingAsset(DOMAIN_SETUP, waera.de, waera.de),
4604=HsHostingAssetRealEntity(DOMAIN_SETUP, xn--wra-qla.de, wära.de), 4604=HsHostingAsset(DOMAIN_SETUP, xn--wra-qla.de, wära.de),
7662=HsHostingAssetRealEntity(DOMAIN_SETUP, dph-netzwerk.de, dph-netzwerk.de) 7662=HsHostingAsset(DOMAIN_SETUP, dph-netzwerk.de, dph-netzwerk.de)
} }
"""); """);
assertThat(firstOfEach(12, domainDnsSetupAssets)).isEqualToIgnoringWhitespace(""" 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": [ ]}), 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=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": [ ]}), 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=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" ]}), 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=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": [ ]}), 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=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." ]}), 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=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": [ ]}), 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=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": [ ]}), 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=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": [ ]}), 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=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\\"" ]}) 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(""" 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": [ "*" ]}), 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=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": [ "*" ]}), 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=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" ]}), 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=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": [ "*" ]}), 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=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" ]}), 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=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": [ "*" ]}), 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=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": [ "*" ]}), 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=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": [ "*" ]}), 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=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": [ "*" ]}) 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(""" 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), 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=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, linuxfanboysngirls.de|MBOX, E-Mail-Empfang-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, 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=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), 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=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), 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=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, mellis.de|MBOX, E-Mail-Empfang-Setup für mellis.de, DOMAIN_SETUP:mellis.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=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), 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=HsHostingAssetRealEntity(DOMAIN_MBOX_SETUP, waera.de|MBOX, E-Mail-Empfang-Setup für waera.de, DOMAIN_SETUP:waera.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=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), 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=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) 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(""" 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), 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=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, linuxfanboysngirls.de|SMTP, E-Mail-Versand-Setup für linuxfanboysngirls.de, DOMAIN_SETUP:linuxfanboysngirls.de, 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=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), 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=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), 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=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, mellis.de|SMTP, E-Mail-Versand-Setup für mellis.de, DOMAIN_SETUP:mellis.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=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), 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=HsHostingAssetRealEntity(DOMAIN_SMTP_SETUP, waera.de|SMTP, E-Mail-Versand-Setup für waera.de, DOMAIN_SETUP:waera.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=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), 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=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) 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(""" 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" ]}), 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=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" ]}), 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=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" ]}), 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=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" ]}), 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=HsHostingAssetRealEntity(EMAIL_ADDRESS, abuse@linuxfanboysngirls.de, abuse@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "abuse", "target": [ "lug00-mars" ]}), 54749=HsHostingAsset(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" ]}), 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=HsHostingAssetRealEntity(EMAIL_ADDRESS, webmaster@linuxfanboysngirls.de, webmaster@linuxfanboysngirls.de, DOMAIN_MBOX_SETUP:linuxfanboysngirls.de|MBOX, {"local-part": "webmaster", "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=HsHostingAssetRealEntity(EMAIL_ADDRESS, abuse@lug-mars.de, abuse@lug-mars.de, DOMAIN_MBOX_SETUP:lug-mars.de|MBOX, {"local-part": "abuse", "target": [ "lug00-marl" ]}), 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=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" ]}), 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=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" ]}), 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=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" ]}), 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=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" ]}) 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() { void validateBookingItems() {
bookingItems.forEach((id, bi) -> { bookingItems.forEach((id, bi) -> {
try { try {
HsBookingItemEntityValidatorRegistry.validated(bi); HsBookingItemEntityValidatorRegistry.validated(em, bi);
} catch (final Exception exc) { } catch (final Exception exc) {
errors.add("validation failed for id:" + id + "( " + bi + "): " + exc.getMessage()); errors.add("validation failed for id:" + id + "( " + bi + "): " + exc.getMessage());
} }
@ -877,21 +879,21 @@ public class ImportHostingAssets extends ImportOfficeData {
assertThat(firstOfEach(15, unixUserAssets)).isEqualToIgnoringWhitespace(""" 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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}), 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=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}) 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); 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) { 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) { private void persistHostingAssets(final Map<Integer, HsHostingAssetRealEntity> assets) {
@ -1064,7 +1066,7 @@ public class ImportHostingAssets extends ImportOfficeData {
.isNull(); .isNull();
final var biType = determineBiType(basepacket_code); final var biType = determineBiType(basepacket_code);
final var bookingItem = HsBookingItemEntity.builder() final var bookingItem = HsBookingItemRealEntity.builder()
.type(biType) .type(biType)
.caption("BI " + packet_name) .caption("BI " + packet_name)
.project(bookingProjects.get(bp_id)) .project(bookingProjects.get(bp_id))
@ -1117,7 +1119,7 @@ public class ImportHostingAssets extends ImportOfficeData {
&& managedWebspace.getRelatedProject().getDebitor().getDebitorNumber() == 10000_00 ) { && managedWebspace.getRelatedProject().getDebitor().getDebitorNumber() == 10000_00 ) {
assertThat(managedWebspace.getIdentifier()).startsWith("xyz"); assertThat(managedWebspace.getIdentifier()).startsWith("xyz");
final var hshDebitor = managedWebspace.getBookingItem().getProject().getDebitor(); final var hshDebitor = managedWebspace.getBookingItem().getProject().getDebitor();
final var newProject = HsBookingProjectEntity.builder() final var newProject = HsBookingProjectRealEntity.builder()
.debitor(hshDebitor) .debitor(hshDebitor)
.caption(parentAsset.getIdentifier() + " Monitor") .caption(parentAsset.getIdentifier() + " Monitor")
.build(); .build();

View File

@ -140,7 +140,8 @@ class HsOfficeDebitorRepositoryIntegrationTest extends ContextBasedTestWithClean
}); });
// then // 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 @Test

View File

@ -161,7 +161,7 @@ class HsOfficeRelationControllerAcceptanceTest extends ContextBasedTestWithClean
.extract().header("Location"); // @formatter:on .extract().header("Location"); // @formatter:on
// finally, the new relation can be accessed under the generated UUID // 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))); location.substring(location.lastIndexOf('/') + 1)));
assertThat(newUserUuid).isNotNull(); 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.rbacgrant.RbacGrantsDiagramService;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleEntity;
import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository; import net.hostsharing.hsadminng.rbac.rbacrole.RbacRoleRepository;
import org.apache.commons.collections4.SetUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -20,6 +21,7 @@ import jakarta.persistence.*;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.regex.Pattern;
import static java.lang.System.out; import static java.lang.System.out;
import static java.util.Comparator.comparing; import static java.util.Comparator.comparing;
@ -55,9 +57,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
private static Long latestIntialTestDataSerialId; private static Long latestIntialTestDataSerialId;
private static boolean countersInitialized = false; private static boolean countersInitialized = false;
private static boolean initialTestDataValidated = false; private static boolean initialTestDataValidated = false;
private static Long initialRbacObjectCount = null; static private Long previousRbacObjectCount;
private static Long initialRbacRoleCount = null; private Long initialRbacObjectCount = null;
private static Long initialRbacGrantCount = null; private Long initialRbacRoleCount = null;
private Long initialRbacGrantCount = null;
private Set<String> initialRbacObjects; private Set<String> initialRbacObjects;
private Set<String> initialRbacRoles; private Set<String> initialRbacRoles;
private Set<String> initialRbacGrants; private Set<String> initialRbacGrants;
@ -119,6 +122,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
@BeforeEach @BeforeEach
//@Transactional -- TODO: check why this does not work but jpaAttempt.transacted does work //@Transactional -- TODO: check why this does not work but jpaAttempt.transacted does work
void retrieveInitialTestData(final TestInfo testInfo) { void retrieveInitialTestData(final TestInfo testInfo) {
this.testInfo = testInfo;
out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".retrieveInitialTestData"); out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".retrieveInitialTestData");
if (latestIntialTestDataSerialId == null ) { if (latestIntialTestDataSerialId == null ) {
@ -126,7 +130,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
} }
if (initialRbacObjects != null){ if (initialRbacObjects != null){
assertNoNewRbacObjectsRolesAndGrantsLeaked(); assertNoNewRbacObjectsRolesAndGrantsLeaked("before");
} }
initialTestDataValidated = false; initialTestDataValidated = false;
@ -156,7 +160,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
assertThat(countersInitialized).as("error while retrieving initial test data").isTrue(); assertThat(countersInitialized).as("error while retrieving initial test data").isTrue();
assertThat(initialTestDataValidated).as("check previous test for leaked 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) { private Long assumeSameInitialCount(final Long countBefore, final long currentCount, final String name) {
@ -166,23 +173,15 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
return currentCount; return currentCount;
} }
@BeforeEach
void keepTestInfo(final TestInfo testInfo) {
this.testInfo = testInfo;
}
@AfterEach @AfterEach
void cleanupAndCheckCleanup(final TestInfo testInfo) { void cleanupAndCheckCleanup(final TestInfo testInfo) {
// If the whole test method has its own transaction, cleanup makes no sense. this.testInfo = testInfo;
// If that transaction even failed, cleaunup would cause an exception.
if (!tm.getTransaction(null).isRollbackOnly()) {
out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".cleanupAndCheckCleanup");
cleanupTemporaryTestData();
repeatUntilTrue(3, this::deleteLeakedRbacObjects);
long rbacObjectCount = assertNoNewRbacObjectsRolesAndGrantsLeaked(); out.println(ContextBasedTestWithCleanup.class.getSimpleName() + ".cleanupAndCheckCleanup");
out.println("TOTAL OBJECT COUNT (after): " + rbacObjectCount); cleanupTemporaryTestData();
} repeatUntilTrue(3, this::deleteLeakedRbacObjects);
assertNoNewRbacObjectsRolesAndGrantsLeaked("after");
} }
private void cleanupTemporaryTestData() { private void cleanupTemporaryTestData() {
@ -207,8 +206,8 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
} }
} }
private long assertNoNewRbacObjectsRolesAndGrantsLeaked() { private void assertNoNewRbacObjectsRolesAndGrantsLeaked(final String event) {
return jpaAttempt.transacted(() -> { long rbacObjectCount = jpaAttempt.transacted(() -> {
context.define("superuser-alex@hostsharing.net"); context.define("superuser-alex@hostsharing.net");
assertEqual(initialRbacObjects, allRbacObjects()); assertEqual(initialRbacObjects, allRbacObjects());
if (DETAILED_BUT_SLOW_CHECK) { 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. // The detailed check works with sets, thus it cannot determine duplicates.
// Therefore, we always compare the counts as well. // Therefore, we always compare the counts as well.
long rbacObjectCount = 0; long count = rbacObjectRepo.count();
assertThat(rbacObjectCount = rbacObjectRepo.count()).as("not all business objects got cleaned up (by current test)") 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); .isEqualTo(initialRbacObjectCount);
assertThat(rbacRoleRepo.count()).as("not all rbac roles got cleaned up (by current test)") assertThat(rbacRoleRepo.count()).as("not all rbac roles got cleaned up (by current test)")
.isEqualTo(initialRbacRoleCount); .isEqualTo(initialRbacRoleCount);
assertThat(rbacGrantRepo.count()).as("not all rbac grants got cleaned up (by current test)") assertThat(rbacGrantRepo.count()).as("not all rbac grants got cleaned up (by current test)")
.isEqualTo(initialRbacGrantCount); .isEqualTo(initialRbacGrantCount);
return rbacObjectCount; return count;
}).assertSuccessful().returnedValue(); }).assertSuccessful().returnedValue();
if (previousRbacObjectCount != null) {
assertThat(rbacObjectCount).as("TOTAL OBJECT COUNT changed from " + previousRbacObjectCount + " to " + rbacObjectCount).isEqualTo(previousRbacObjectCount);
}
previousRbacObjectCount = rbacObjectCount;
} }
private boolean deleteLeakedRbacObjects() { private boolean deleteLeakedRbacObjects() {
final var deletionSuccessful = new AtomicBoolean(true); final var deletionSuccessful = new AtomicBoolean(true);
rbacObjectRepo.findAll().stream() jpaAttempt.transacted(() -> rbacObjectRepo.findAll()).assertSuccessful().returnedValue().stream()
.filter(o -> o.serialId > latestIntialTestDataSerialId) .filter(o -> latestIntialTestDataSerialId != null && o.serialId > latestIntialTestDataSerialId)
.sorted(comparing(o -> o.serialId)) .sorted(comparing(o -> o.serialId))
.forEach(o -> { .forEach(o -> {
final var exception = jpaAttempt.transacted(() -> { 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) { private void assertEqual(final Set<String> before, final Set<String> after) {
assertThat(before).isNotNull(); assertThat(before).isNotNull();
assertThat(after).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(); 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) { protected void generateRbacDiagramForCurrentSubjects(final EnumSet<RbacGrantsDiagramService.Include> include, final String name) {
RbacGrantsDiagramService.writeToFile( RbacGrantsDiagramService.writeToFile(
name, name,
@ -303,7 +329,10 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
/** /**
* Generates a diagram of the RBAC-Grants for the given object and permission. * 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) { protected void generateRbacDiagramForObjectPermission(final UUID targetObject, final String rbacOp, final String name) {
RbacGrantsDiagramService.writeToFile( RbacGrantsDiagramService.writeToFile(
name, name,

View File

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

View File

@ -66,7 +66,8 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
// then // then
result.assertExceptionWithRootCauseMessage( result.assertExceptionWithRootCauseMessage(
PersistenceException.class, 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 @Test
@ -84,7 +85,8 @@ class TestCustomerRepositoryIntegrationTest extends ContextBasedTest {
// then // then
result.assertExceptionWithRootCauseMessage( result.assertExceptionWithRootCauseMessage(
PersistenceException.class, 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}");
} }