add assigned-asset, add more hosting-asset test-data and introduce HsBookingDebitor+hs_booking_debitor_rv (#58)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #58 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
parent
c23baca47a
commit
fc2b437a55
@ -0,0 +1,55 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.booking.debitor;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||||
|
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||||
|
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||||
|
|
||||||
|
// a partial HsOfficeDebitorEntity to reduce the number of SQL queries to load the entity
|
||||||
|
@Entity
|
||||||
|
@Table(name = "hs_booking_debitor_rv")
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@DisplayName("BookingDebitor")
|
||||||
|
public class HsBookingDebitorEntity implements Stringifyable {
|
||||||
|
|
||||||
|
public static final String DEBITOR_NUMBER_TAG = "D-";
|
||||||
|
|
||||||
|
private static Stringify<HsBookingDebitorEntity> stringify =
|
||||||
|
stringify(HsBookingDebitorEntity.class, "booking-debitor")
|
||||||
|
.withIdProp(HsBookingDebitorEntity::toShortString)
|
||||||
|
.withProp(HsBookingDebitorEntity::getDefaultPrefix)
|
||||||
|
.quotedValues(false);
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private UUID uuid;
|
||||||
|
|
||||||
|
@Column(name = "debitornumber")
|
||||||
|
private Integer debitorNumber;
|
||||||
|
|
||||||
|
@Column(name = "defaultprefix", columnDefinition = "char(3) not null")
|
||||||
|
private String defaultPrefix;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return stringify.apply(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toShortString() {
|
||||||
|
return DEBITOR_NUMBER_TAG + debitorNumber;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.booking.debitor;
|
||||||
|
|
||||||
|
import org.springframework.data.repository.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface HsBookingDebitorRepository extends Repository<HsBookingDebitorEntity, UUID> {
|
||||||
|
|
||||||
|
Optional<HsBookingDebitorEntity> findByUuid(UUID id);
|
||||||
|
|
||||||
|
List<HsBookingDebitorEntity> findByDebitorNumber(int debitorNumber);
|
||||||
|
}
|
@ -160,6 +160,10 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject, Validatab
|
|||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HsBookingProjectEntity getRelatedProject() {
|
||||||
|
return project != null ? project : parentItem.getRelatedProject();
|
||||||
|
}
|
||||||
|
|
||||||
public static RbacView rbac() {
|
public static RbacView rbac() {
|
||||||
return rbacViewFor("bookingItem", HsBookingItemEntity.class)
|
return rbacViewFor("bookingItem", HsBookingItemEntity.class)
|
||||||
.withIdentityView(SQL.projection("caption"))
|
.withIdentityView(SQL.projection("caption"))
|
||||||
@ -198,6 +202,6 @@ public class HsBookingItemEntity implements Stringifyable, RbacObject, Validatab
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
rbac().generateWithBaseFileName("6-hs-booking/620-booking-item/6203-hs-booking-item-rbac");
|
rbac().generateWithBaseFileName("6-hs-booking/630-booking-item/6303-hs-booking-item-rbac");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,10 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public interface HsBookingItemRepository extends Repository<HsBookingItemEntity, UUID> {
|
public interface HsBookingItemRepository extends Repository<HsBookingItemEntity, UUID> {
|
||||||
|
|
||||||
List<HsBookingItemEntity> findAll();
|
|
||||||
Optional<HsBookingItemEntity> findByUuid(final UUID bookingItemUuid);
|
Optional<HsBookingItemEntity> findByUuid(final UUID bookingItemUuid);
|
||||||
|
|
||||||
|
List<HsBookingItemEntity> findByCaption(String bookingItemCaption);
|
||||||
|
|
||||||
List<HsBookingItemEntity> findAllByProjectUuid(final UUID projectItemUuid);
|
List<HsBookingItemEntity> findAllByProjectUuid(final UUID projectItemUuid);
|
||||||
|
|
||||||
HsBookingItemEntity save(HsBookingItemEntity current);
|
HsBookingItemEntity save(HsBookingItemEntity current);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.booking.project;
|
package net.hostsharing.hsadminng.hs.booking.project;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjectsApi;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.api.HsBookingProjectsApi;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectInsertResource;
|
||||||
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource;
|
import net.hostsharing.hsadminng.hs.booking.generated.api.v1.model.HsBookingProjectPatchResource;
|
||||||
@ -12,8 +13,10 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
|
||||||
|
|
||||||
|
import jakarta.persistence.EntityNotFoundException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class HsBookingProjectController implements HsBookingProjectsApi {
|
public class HsBookingProjectController implements HsBookingProjectsApi {
|
||||||
@ -27,6 +30,9 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private HsBookingProjectRepository bookingProjectRepo;
|
private HsBookingProjectRepository bookingProjectRepo;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HsBookingDebitorRepository debitorRepo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseEntity<List<HsBookingProjectResource>> listBookingProjectsByDebitorUuid(
|
public ResponseEntity<List<HsBookingProjectResource>> listBookingProjectsByDebitorUuid(
|
||||||
@ -50,7 +56,7 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
|||||||
|
|
||||||
context.define(currentUser, assumedRoles);
|
context.define(currentUser, assumedRoles);
|
||||||
|
|
||||||
final var entityToSave = mapper.map(body, HsBookingProjectEntity.class);
|
final var entityToSave = mapper.map(body, HsBookingProjectEntity.class, RESOURCE_TO_ENTITY_POSTMAPPER);
|
||||||
|
|
||||||
final var saved = bookingProjectRepo.save(entityToSave);
|
final var saved = bookingProjectRepo.save(entityToSave);
|
||||||
|
|
||||||
@ -111,4 +117,12 @@ public class HsBookingProjectController implements HsBookingProjectsApi {
|
|||||||
final var mapped = mapper.map(saved, HsBookingProjectResource.class);
|
final var mapped = mapper.map(saved, HsBookingProjectResource.class);
|
||||||
return ResponseEntity.ok(mapped);
|
return ResponseEntity.ok(mapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final BiConsumer<HsBookingProjectInsertResource, HsBookingProjectEntity> RESOURCE_TO_ENTITY_POSTMAPPER = (resource, entity) -> {
|
||||||
|
if (resource.getDebitorUuid() != null) {
|
||||||
|
entity.setDebitor(debitorRepo.findByUuid(resource.getDebitorUuid())
|
||||||
|
.orElseThrow(() -> new EntityNotFoundException("ERROR: [400] debitorUuid %s not found".formatted(
|
||||||
|
resource.getDebitorUuid()))));
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.booking.project;
|
package net.hostsharing.hsadminng.hs.booking.project;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
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.HsOfficeRelationEntity;
|
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationEntity;
|
||||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||||
@ -49,7 +50,7 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject {
|
|||||||
|
|
||||||
@ManyToOne(optional = false)
|
@ManyToOne(optional = false)
|
||||||
@JoinColumn(name = "debitoruuid")
|
@JoinColumn(name = "debitoruuid")
|
||||||
private HsOfficeDebitorEntity debitor;
|
private HsBookingDebitorEntity debitor;
|
||||||
|
|
||||||
@Column(name = "caption")
|
@Column(name = "caption")
|
||||||
private String caption;
|
private String caption;
|
||||||
@ -61,7 +62,7 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toShortString() {
|
public String toShortString() {
|
||||||
return ofNullable(debitor).map(HsOfficeDebitorEntity::toShortString).orElse("D-???????") +
|
return ofNullable(debitor).map(HsBookingDebitorEntity::toShortString).orElse("D-???????") +
|
||||||
":" + caption;
|
":" + caption;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,6 +109,6 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
rbac().generateWithBaseFileName("6-hs-booking/610-booking-project/6103-hs-booking-project-rbac");
|
rbac().generateWithBaseFileName("6-hs-booking/620-booking-project/6203-hs-booking-project-rbac");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public interface HsBookingProjectRepository extends Repository<HsBookingProjectEntity, UUID> {
|
public interface HsBookingProjectRepository extends Repository<HsBookingProjectEntity, UUID> {
|
||||||
|
|
||||||
List<HsBookingProjectEntity> findAll();
|
|
||||||
Optional<HsBookingProjectEntity> findByUuid(final UUID bookingProjectUuid);
|
Optional<HsBookingProjectEntity> findByUuid(final UUID bookingProjectUuid);
|
||||||
|
List<HsBookingProjectEntity> findByCaption(final String projectCaption);
|
||||||
|
|
||||||
List<HsBookingProjectEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
|
List<HsBookingProjectEntity> findAllByDebitorUuid(final UUID bookingProjectUuid);
|
||||||
|
|
||||||
|
@ -33,9 +33,7 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Column.dependsOnColumn;
|
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.ColumnValue.usingDefaultCase;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.GLOBAL;
|
||||||
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
|
import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.Nullable.NULLABLE;
|
||||||
@ -65,6 +63,7 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata
|
|||||||
.withProp(HsHostingAssetEntity::getIdentifier)
|
.withProp(HsHostingAssetEntity::getIdentifier)
|
||||||
.withProp(HsHostingAssetEntity::getCaption)
|
.withProp(HsHostingAssetEntity::getCaption)
|
||||||
.withProp(HsHostingAssetEntity::getParentAsset)
|
.withProp(HsHostingAssetEntity::getParentAsset)
|
||||||
|
.withProp(HsHostingAssetEntity::getAssignedToAsset)
|
||||||
.withProp(HsHostingAssetEntity::getBookingItem)
|
.withProp(HsHostingAssetEntity::getBookingItem)
|
||||||
.withProp(HsHostingAssetEntity::getConfig)
|
.withProp(HsHostingAssetEntity::getConfig)
|
||||||
.quotedValues(false);
|
.quotedValues(false);
|
||||||
@ -84,6 +83,10 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata
|
|||||||
@JoinColumn(name = "parentassetuuid")
|
@JoinColumn(name = "parentassetuuid")
|
||||||
private HsHostingAssetEntity parentAsset;
|
private HsHostingAssetEntity parentAsset;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "assignedtoassetuuid")
|
||||||
|
private HsHostingAssetEntity assignedToAsset;
|
||||||
|
|
||||||
@Column(name = "type")
|
@Column(name = "type")
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private HsHostingAssetType type;
|
private HsHostingAssetType type;
|
||||||
@ -144,12 +147,17 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata
|
|||||||
NULLABLE)
|
NULLABLE)
|
||||||
.toRole("bookingItem", AGENT).grantPermission(INSERT)
|
.toRole("bookingItem", AGENT).grantPermission(INSERT)
|
||||||
|
|
||||||
.importEntityAlias("parentAsset", HsHostingAssetEntity.class, usingCase(MANAGED_SERVER),
|
.importEntityAlias("parentAsset", HsHostingAssetEntity.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(),
|
||||||
|
dependsOnColumn("assignedToAssetUuid"),
|
||||||
|
directlyFetchedByDependsOnColumn(),
|
||||||
|
NULLABLE)
|
||||||
|
|
||||||
.createRole(OWNER, (with) -> {
|
.createRole(OWNER, (with) -> {
|
||||||
with.incomingSuperRole("bookingItem", ADMIN);
|
with.incomingSuperRole("bookingItem", ADMIN);
|
||||||
with.incomingSuperRole("parentAsset", ADMIN);
|
with.incomingSuperRole("parentAsset", ADMIN);
|
||||||
@ -160,13 +168,15 @@ public class HsHostingAssetEntity implements Stringifyable, RbacObject, Validata
|
|||||||
with.incomingSuperRole("parentAsset", AGENT);
|
with.incomingSuperRole("parentAsset", AGENT);
|
||||||
with.permission(UPDATE);
|
with.permission(UPDATE);
|
||||||
})
|
})
|
||||||
.createSubRole(AGENT)
|
.createSubRole(AGENT, (with) -> {
|
||||||
|
with.outgoingSubRole("assignedToAsset", TENANT);
|
||||||
|
})
|
||||||
.createSubRole(TENANT, (with) -> {
|
.createSubRole(TENANT, (with) -> {
|
||||||
with.outgoingSubRole("bookingItem", TENANT);
|
with.outgoingSubRole("bookingItem", TENANT);
|
||||||
with.outgoingSubRole("parentAsset", TENANT);
|
with.outgoingSubRole("parentAsset", TENANT);
|
||||||
with.permission(SELECT);
|
with.permission(SELECT);
|
||||||
})
|
})
|
||||||
.limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentServer", "global");
|
.limitDiagramTo("asset", "bookingItem", "bookingItem.debitorRel", "parentAsset", "assignedToAsset", "global");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
|
@ -10,9 +10,10 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public interface HsHostingAssetRepository extends Repository<HsHostingAssetEntity, UUID> {
|
public interface HsHostingAssetRepository extends Repository<HsHostingAssetEntity, UUID> {
|
||||||
|
|
||||||
List<HsHostingAssetEntity> findAll();
|
|
||||||
Optional<HsHostingAssetEntity> findByUuid(final UUID serverUuid);
|
Optional<HsHostingAssetEntity> findByUuid(final UUID serverUuid);
|
||||||
|
|
||||||
|
List<HsHostingAssetEntity> findByIdentifier(String assetIdentifier);
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
SELECT asset FROM HsHostingAssetEntity asset
|
SELECT asset FROM HsHostingAssetEntity asset
|
||||||
WHERE (:projectUuid IS NULL OR asset.bookingItem.project.uuid = :projectUuid)
|
WHERE (:projectUuid IS NULL OR asset.bookingItem.project.uuid = :projectUuid)
|
||||||
|
@ -6,11 +6,13 @@ public enum HsHostingAssetType {
|
|||||||
MANAGED_SERVER, // named e.g. vm1234
|
MANAGED_SERVER, // named e.g. vm1234
|
||||||
MANAGED_WEBSPACE(MANAGED_SERVER), // named eg. xyz00
|
MANAGED_WEBSPACE(MANAGED_SERVER), // named eg. xyz00
|
||||||
UNIX_USER(MANAGED_WEBSPACE), // named e.g. xyz00-abc
|
UNIX_USER(MANAGED_WEBSPACE), // named e.g. xyz00-abc
|
||||||
DOMAIN_SETUP(UNIX_USER), // named e.g. example.org
|
DOMAIN_DNS_SETUP(MANAGED_WEBSPACE), // named e.g. example.org
|
||||||
|
DOMAIN_HTTP_SETUP(MANAGED_WEBSPACE), // named e.g. example.org
|
||||||
|
DOMAIN_EMAIL_SETUP(MANAGED_WEBSPACE), // named e.g. example.org
|
||||||
|
|
||||||
// TODO.spec: SECURE_MX
|
// TODO.spec: SECURE_MX
|
||||||
EMAIL_ALIAS(MANAGED_WEBSPACE), // named e.g. xyz00-abc
|
EMAIL_ALIAS(MANAGED_WEBSPACE), // named e.g. xyz00-abc
|
||||||
EMAIL_ADDRESS(DOMAIN_SETUP), // named e.g. sample@example.org
|
EMAIL_ADDRESS(DOMAIN_EMAIL_SETUP), // named e.g. sample@example.org
|
||||||
PGSQL_USER(MANAGED_WEBSPACE), // named e.g. xyz00_abc
|
PGSQL_USER(MANAGED_WEBSPACE), // named e.g. xyz00_abc
|
||||||
PGSQL_DATABASE(MANAGED_WEBSPACE), // named e.g. xyz00_abc, TODO.spec: or PGSQL_USER?
|
PGSQL_DATABASE(MANAGED_WEBSPACE), // named e.g. xyz00_abc, TODO.spec: or PGSQL_USER?
|
||||||
MARIADB_USER(MANAGED_WEBSPACE), // named e.g. xyz00_abc
|
MARIADB_USER(MANAGED_WEBSPACE), // named e.g. xyz00_abc
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
package net.hostsharing.hsadminng.hs.hosting.asset.validators;
|
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType;
|
|
||||||
import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
|
||||||
|
|
||||||
class HsCloudServerHostingAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
|
||||||
|
|
||||||
public HsCloudServerHostingAssetValidator() {
|
|
||||||
super(
|
|
||||||
integerProperty("CPUs").min(1).max(32).required(),
|
|
||||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
|
||||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
|
||||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
|
||||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,7 +20,7 @@ public class HsHostingAssetEntityValidators {
|
|||||||
|
|
||||||
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType>> validators = new HashMap<>();
|
private static final Map<Enum<HsHostingAssetType>, HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType>> validators = new HashMap<>();
|
||||||
static {
|
static {
|
||||||
register(CLOUD_SERVER, new HsCloudServerHostingAssetValidator());
|
register(CLOUD_SERVER, new HsEntityValidator<>());
|
||||||
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
|
register(MANAGED_SERVER, new HsManagedServerHostingAssetValidator());
|
||||||
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
register(MANAGED_WEBSPACE, new HsManagedWebspaceHostingAssetValidator());
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,13 @@ class HsManagedServerHostingAssetValidator extends HsEntityValidator<HsHostingAs
|
|||||||
|
|
||||||
public HsManagedServerHostingAssetValidator() {
|
public HsManagedServerHostingAssetValidator() {
|
||||||
super(
|
super(
|
||||||
integerProperty("CPUs").min(1).max(32).required(),
|
integerProperty("monit_min_free_ssd").min(1).max(1000).optional(),
|
||||||
integerProperty("RAM").unit("GB").min(1).max(128).required(),
|
integerProperty("monit_min_free_hdd").min(1).max(4000).optional(),
|
||||||
integerProperty("SSD").unit("GB").min(25).max(1000).step(25).required(),
|
integerProperty("monit_max_ssd_usage").unit("%").min(10).max(100).required(),
|
||||||
integerProperty("HDD").unit("GB").min(0).max(4000).step(250).optional(),
|
integerProperty("monit_max_hdd_usage").unit("%").min(10).max(100).optional(),
|
||||||
integerProperty("Traffic").unit("GB").min(250).max(10000).step(250).required()
|
integerProperty("monit_max_cpu_usage").unit("%").min(10).max(100).required(),
|
||||||
|
integerProperty("monit_max_ram_usage").unit("%").min(10).max(100).required()
|
||||||
|
// TODO: stringProperty("monit_alarm_email").unit("GB").optional()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,9 @@ import net.hostsharing.hsadminng.hs.validation.HsEntityValidator;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.validation.IntegerPropertyValidator.integerProperty;
|
|
||||||
|
|
||||||
class HsManagedWebspaceHostingAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
class HsManagedWebspaceHostingAssetValidator extends HsEntityValidator<HsHostingAssetEntity, HsHostingAssetType> {
|
||||||
public HsManagedWebspaceHostingAssetValidator() {
|
public HsManagedWebspaceHostingAssetValidator() {
|
||||||
super(
|
|
||||||
integerProperty("SSD").unit("GB").min(1).max(100).step(1).required(),
|
|
||||||
integerProperty("HDD").unit("GB").min(0).max(250).step(10).optional(),
|
|
||||||
integerProperty("Traffic").unit("GB").min(10).max(1000).step(10).required()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -10,7 +10,9 @@ components:
|
|||||||
- MANAGED_SERVER
|
- MANAGED_SERVER
|
||||||
- MANAGED_WEBSPACE
|
- MANAGED_WEBSPACE
|
||||||
- UNIX_USER
|
- UNIX_USER
|
||||||
- DOMAIN_SETUP
|
- DOMAIN_DNS_SETUP
|
||||||
|
- DOMAIN_HTTP_SETUP
|
||||||
|
- DOMAIN_EMAIL_SETUP
|
||||||
- EMAIL_ALIAS
|
- EMAIL_ALIAS
|
||||||
- EMAIL_ADDRESS
|
- EMAIL_ADDRESS
|
||||||
- PGSQL_USER
|
- PGSQL_USER
|
||||||
|
@ -118,10 +118,13 @@ begin
|
|||||||
sql = format($sql$
|
sql = format($sql$
|
||||||
create or replace function %1$sUuidByIdName(givenIdName varchar)
|
create or replace function %1$sUuidByIdName(givenIdName varchar)
|
||||||
returns uuid
|
returns uuid
|
||||||
language sql
|
language plpgsql as $f$
|
||||||
strict as $f$
|
declare
|
||||||
select uuid from %1$s_iv iv where iv.idName = givenIdName;
|
singleMatch uuid;
|
||||||
$f$;
|
begin
|
||||||
|
select uuid into strict singleMatch from %1$s_iv iv where iv.idName = givenIdName;
|
||||||
|
return singleMatch;
|
||||||
|
end; $f$;
|
||||||
$sql$, targetTable);
|
$sql$, targetTable);
|
||||||
execute sql;
|
execute sql;
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
--liquibase formatted sql
|
||||||
|
|
||||||
|
-- ============================================================================
|
||||||
|
--changeset hs-booking-debitor-RESTRICTED-VIEW:1 endDelimiter:--//
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
create view hs_booking_debitor_rv as
|
||||||
|
select debitor.uuid,
|
||||||
|
debitor.version,
|
||||||
|
(partner.partnerNumber::varchar || debitor.debitorNumberSuffix)::numeric as debitorNumber,
|
||||||
|
debitor.defaultPrefix
|
||||||
|
from hs_office_debitor_rv debitor
|
||||||
|
-- RBAC for debitor is sufficient, for faster access we are bypassing RBAC for the join tables
|
||||||
|
join hs_office_relation debitorRel on debitor.debitorReluUid=debitorRel.uuid
|
||||||
|
join hs_office_relation partnerRel on partnerRel.holderUuid=debitorRel.anchorUuid
|
||||||
|
join hs_office_partner partner on partner.partnerReluUid=partnerRel.uuid;
|
||||||
|
--//
|
@ -9,7 +9,9 @@ create type HsHostingAssetType as enum (
|
|||||||
'MANAGED_SERVER',
|
'MANAGED_SERVER',
|
||||||
'MANAGED_WEBSPACE',
|
'MANAGED_WEBSPACE',
|
||||||
'UNIX_USER',
|
'UNIX_USER',
|
||||||
'DOMAIN_SETUP',
|
'DOMAIN_DNS_SETUP',
|
||||||
|
'DOMAIN_HTTP_SETUP',
|
||||||
|
'DOMAIN_EMAIL_SETUP',
|
||||||
'EMAIL_ALIAS',
|
'EMAIL_ALIAS',
|
||||||
'EMAIL_ADDRESS',
|
'EMAIL_ADDRESS',
|
||||||
'PGSQL_USER',
|
'PGSQL_USER',
|
||||||
@ -27,6 +29,7 @@ create table if not exists hs_hosting_asset
|
|||||||
bookingItemUuid uuid null references hs_booking_item(uuid),
|
bookingItemUuid uuid null references hs_booking_item(uuid),
|
||||||
type HsHostingAssetType not null,
|
type HsHostingAssetType not null,
|
||||||
parentAssetUuid uuid null references hs_hosting_asset(uuid) initially deferred,
|
parentAssetUuid uuid null references hs_hosting_asset(uuid) initially deferred,
|
||||||
|
assignedToAssetUuid uuid null references hs_hosting_asset(uuid) initially deferred,
|
||||||
identifier varchar(80) not null,
|
identifier varchar(80) not null,
|
||||||
caption varchar(80),
|
caption varchar(80),
|
||||||
config jsonb not null,
|
config jsonb not null,
|
||||||
@ -59,9 +62,11 @@ begin
|
|||||||
when 'MANAGED_SERVER' then null
|
when 'MANAGED_SERVER' then null
|
||||||
when 'MANAGED_WEBSPACE' then 'MANAGED_SERVER'
|
when 'MANAGED_WEBSPACE' then 'MANAGED_SERVER'
|
||||||
when 'UNIX_USER' then 'MANAGED_WEBSPACE'
|
when 'UNIX_USER' then 'MANAGED_WEBSPACE'
|
||||||
when 'DOMAIN_SETUP' then 'UNIX_USER'
|
when 'DOMAIN_DNS_SETUP' then 'MANAGED_WEBSPACE'
|
||||||
|
when 'DOMAIN_HTTP_SETUP' then 'MANAGED_WEBSPACE'
|
||||||
|
when 'DOMAIN_EMAIL_SETUP' then 'MANAGED_WEBSPACE'
|
||||||
when 'EMAIL_ALIAS' then 'MANAGED_WEBSPACE'
|
when 'EMAIL_ALIAS' then 'MANAGED_WEBSPACE'
|
||||||
when 'EMAIL_ADDRESS' then 'DOMAIN_SETUP'
|
when 'EMAIL_ADDRESS' then 'DOMAIN_EMAIL_SETUP'
|
||||||
when 'PGSQL_USER' then 'MANAGED_WEBSPACE'
|
when 'PGSQL_USER' then 'MANAGED_WEBSPACE'
|
||||||
when 'PGSQL_DATABASE' then 'MANAGED_WEBSPACE'
|
when 'PGSQL_DATABASE' then 'MANAGED_WEBSPACE'
|
||||||
when 'MARIADB_USER' then 'MANAGED_WEBSPACE'
|
when 'MARIADB_USER' then 'MANAGED_WEBSPACE'
|
||||||
|
@ -25,40 +25,30 @@ subgraph asset["`**asset**`"]
|
|||||||
perm:asset:INSERT{{asset:INSERT}}
|
perm:asset:INSERT{{asset:INSERT}}
|
||||||
perm:asset:DELETE{{asset:DELETE}}
|
perm:asset:DELETE{{asset:DELETE}}
|
||||||
perm:asset:UPDATE{{asset:UPDATE}}
|
perm:asset:UPDATE{{asset:UPDATE}}
|
||||||
perm:asset:SELECT{{asset:SELECT}}
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph bookingItem["`**bookingItem**`"]
|
subgraph assignedToAsset["`**assignedToAsset**`"]
|
||||||
direction TB
|
direction TB
|
||||||
style bookingItem fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
style assignedToAsset fill:#99bcdb,stroke:#274d6e,stroke-width:8px
|
||||||
|
|
||||||
subgraph bookingItem:roles[ ]
|
subgraph assignedToAsset:roles[ ]
|
||||||
style bookingItem:roles fill:#99bcdb,stroke:white
|
style assignedToAsset:roles fill:#99bcdb,stroke:white
|
||||||
|
|
||||||
role:bookingItem:OWNER[[bookingItem:OWNER]]
|
role:assignedToAsset:TENANT[[assignedToAsset:TENANT]]
|
||||||
role:bookingItem:ADMIN[[bookingItem:ADMIN]]
|
|
||||||
role:bookingItem:AGENT[[bookingItem:AGENT]]
|
|
||||||
role:bookingItem:TENANT[[bookingItem:TENANT]]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
%% granting roles to roles
|
%% granting roles to roles
|
||||||
role:bookingItem:OWNER -.-> role:bookingItem:ADMIN
|
|
||||||
role:bookingItem:ADMIN -.-> role:bookingItem:AGENT
|
|
||||||
role:bookingItem:AGENT -.-> role:bookingItem:TENANT
|
|
||||||
role:bookingItem:ADMIN ==> role:asset:OWNER
|
|
||||||
role:asset:OWNER ==> role:asset:ADMIN
|
role:asset:OWNER ==> role:asset:ADMIN
|
||||||
role:bookingItem:AGENT ==> role:asset:ADMIN
|
|
||||||
role:asset:ADMIN ==> role:asset:AGENT
|
role:asset:ADMIN ==> role:asset:AGENT
|
||||||
|
role:asset:AGENT ==> role:assignedToAsset:TENANT
|
||||||
role:asset:AGENT ==> role:asset:TENANT
|
role:asset:AGENT ==> role:asset:TENANT
|
||||||
role:asset:TENANT ==> role:bookingItem:TENANT
|
role:assignedToAsset:TENANT ==> role:asset:TENANT
|
||||||
|
|
||||||
%% granting permissions to roles
|
%% granting permissions to roles
|
||||||
role:global:ADMIN ==> perm:asset:INSERT
|
role:global:ADMIN ==> perm:asset:INSERT
|
||||||
role:bookingItem:AGENT ==> perm:asset:INSERT
|
|
||||||
role:asset:OWNER ==> perm:asset:DELETE
|
role:asset:OWNER ==> perm:asset:DELETE
|
||||||
role:asset:ADMIN ==> perm:asset:UPDATE
|
role:asset:ADMIN ==> perm:asset:UPDATE
|
||||||
role:asset:TENANT ==> perm:asset:SELECT
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -31,6 +31,7 @@ create or replace procedure buildRbacSystemForHsHostingAsset(
|
|||||||
|
|
||||||
declare
|
declare
|
||||||
newBookingItem hs_booking_item;
|
newBookingItem hs_booking_item;
|
||||||
|
newAssignedToAsset hs_hosting_asset;
|
||||||
newParentAsset hs_hosting_asset;
|
newParentAsset hs_hosting_asset;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
@ -38,6 +39,8 @@ begin
|
|||||||
|
|
||||||
SELECT * FROM hs_booking_item WHERE uuid = NEW.bookingItemUuid INTO newBookingItem;
|
SELECT * FROM hs_booking_item WHERE uuid = NEW.bookingItemUuid INTO newBookingItem;
|
||||||
|
|
||||||
|
SELECT * FROM hs_hosting_asset WHERE uuid = NEW.assignedToAssetUuid INTO newAssignedToAsset;
|
||||||
|
|
||||||
SELECT * FROM hs_hosting_asset WHERE uuid = NEW.parentAssetUuid INTO newParentAsset;
|
SELECT * FROM hs_hosting_asset WHERE uuid = NEW.parentAssetUuid INTO newParentAsset;
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
@ -59,13 +62,15 @@ begin
|
|||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsHostingAssetAGENT(NEW),
|
hsHostingAssetAGENT(NEW),
|
||||||
incomingSuperRoles => array[hsHostingAssetADMIN(NEW)]
|
incomingSuperRoles => array[hsHostingAssetADMIN(NEW)],
|
||||||
|
outgoingSubRoles => array[hsHostingAssetTENANT(newAssignedToAsset)]
|
||||||
);
|
);
|
||||||
|
|
||||||
perform createRoleWithGrants(
|
perform createRoleWithGrants(
|
||||||
hsHostingAssetTENANT(NEW),
|
hsHostingAssetTENANT(NEW),
|
||||||
permissions => array['SELECT'],
|
incomingSuperRoles => array[
|
||||||
incomingSuperRoles => array[hsHostingAssetAGENT(NEW)],
|
hsHostingAssetAGENT(NEW),
|
||||||
|
hsHostingAssetTENANT(newAssignedToAsset)],
|
||||||
outgoingSubRoles => array[
|
outgoingSubRoles => array[
|
||||||
hsBookingItemTENANT(newBookingItem),
|
hsBookingItemTENANT(newBookingItem),
|
||||||
hsHostingAssetTENANT(newParentAsset)]
|
hsHostingAssetTENANT(newParentAsset)]
|
||||||
@ -197,11 +202,11 @@ create or replace function new_hs_hosting_asset_grants_insert_to_hs_hosting_asse
|
|||||||
language plpgsql
|
language plpgsql
|
||||||
strict as $$
|
strict as $$
|
||||||
begin
|
begin
|
||||||
if NEW.type = 'MANAGED_SERVER' then
|
-- unconditional for all rows in that table
|
||||||
call grantPermissionToRole(
|
call grantPermissionToRole(
|
||||||
createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'),
|
createPermission(NEW.uuid, 'INSERT', 'hs_hosting_asset'),
|
||||||
hsHostingAssetADMIN(NEW));
|
hsHostingAssetADMIN(NEW));
|
||||||
end if;
|
-- end.
|
||||||
return NEW;
|
return NEW;
|
||||||
end; $$;
|
end; $$;
|
||||||
|
|
||||||
|
@ -16,7 +16,11 @@ declare
|
|||||||
relatedDebitor hs_office_debitor;
|
relatedDebitor hs_office_debitor;
|
||||||
relatedPrivateCloudBookingItem hs_booking_item;
|
relatedPrivateCloudBookingItem hs_booking_item;
|
||||||
relatedManagedServerBookingItem hs_booking_item;
|
relatedManagedServerBookingItem hs_booking_item;
|
||||||
|
debitorNumberSuffix varchar;
|
||||||
|
defaultPrefix varchar;
|
||||||
managedServerUuid uuid;
|
managedServerUuid uuid;
|
||||||
|
managedWebspaceUuid uuid;
|
||||||
|
webUnixUserUuid uuid;
|
||||||
begin
|
begin
|
||||||
currentTask := 'creating hosting-asset test-data ' || givenProjectCaption;
|
currentTask := 'creating hosting-asset test-data ' || givenProjectCaption;
|
||||||
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
call defineContext(currentTask, null, 'superuser-alex@hostsharing.net', 'global#global:ADMIN');
|
||||||
@ -45,12 +49,18 @@ begin
|
|||||||
assert relatedManagedServerBookingItem.uuid is not null, 'relatedManagedServerBookingItem for "' || givenProjectCaption|| '" must not be null';
|
assert relatedManagedServerBookingItem.uuid is not null, 'relatedManagedServerBookingItem for "' || givenProjectCaption|| '" must not be null';
|
||||||
|
|
||||||
select uuid_generate_v4() into managedServerUuid;
|
select uuid_generate_v4() into managedServerUuid;
|
||||||
|
select uuid_generate_v4() into managedWebspaceUuid;
|
||||||
|
select uuid_generate_v4() into webUnixUserUuid;
|
||||||
|
debitorNumberSuffix := relatedDebitor.debitorNumberSuffix;
|
||||||
|
defaultPrefix := relatedDebitor.defaultPrefix;
|
||||||
|
|
||||||
insert into hs_hosting_asset
|
insert into hs_hosting_asset
|
||||||
(uuid, bookingitemuuid, type, parentAssetUuid, identifier, caption, config)
|
(uuid, bookingitemuuid, type, parentAssetUuid, assignedToAssetUuid, identifier, caption, config)
|
||||||
values (managedServerUuid, relatedPrivateCloudBookingItem.uuid, 'MANAGED_SERVER', null, 'vm10' || relatedDebitor.debitorNumberSuffix, 'some ManagedServer', '{ "CPU": 2, "SDD": 512, "extra": 42 }'::jsonb),
|
values (managedServerUuid, relatedPrivateCloudBookingItem.uuid, 'MANAGED_SERVER', null, null, 'vm10' || debitorNumberSuffix, 'some ManagedServer', '{ "extra": 42 }'::jsonb),
|
||||||
(uuid_generate_v4(), relatedPrivateCloudBookingItem.uuid, 'CLOUD_SERVER', null, 'vm20' || relatedDebitor.debitorNumberSuffix, 'another CloudServer', '{ "CPU": 2, "HDD": 1024, "extra": 42 }'::jsonb),
|
(uuid_generate_v4(), relatedPrivateCloudBookingItem.uuid, 'CLOUD_SERVER', null, null, 'vm20' || debitorNumberSuffix, 'another CloudServer', '{ "extra": 42 }'::jsonb),
|
||||||
(uuid_generate_v4(), relatedManagedServerBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, relatedDebitor.defaultPrefix || '01', 'some Webspace', '{ "RAM": 1, "SDD": 512, "HDD": 2048, "extra": 42 }'::jsonb);
|
(managedWebspaceUuid, relatedManagedServerBookingItem.uuid, 'MANAGED_WEBSPACE', managedServerUuid, null, defaultPrefix || '01', 'some Webspace', '{ "extra": 42 }'::jsonb),
|
||||||
|
(webUnixUserUuid, null, 'UNIX_USER', managedWebspaceUuid, null, defaultPrefix || '01-web', 'some UnixUser for Website', '{ "SSD-soft-quota": "128", "SSD-hard-quota": "256", "HDD-soft-quota": "512", "HDD-hard-quota": "1024", "extra": 42 }'::jsonb),
|
||||||
|
(uuid_generate_v4(), null, 'DOMAIN_HTTP_SETUP', managedWebspaceUuid, webUnixUserUuid, defaultPrefix || '.example.org', 'some Domain-HTTP-Setup', '{ "option-htdocsfallback": true, "use-fcgiphpbin": "/usr/lib/cgi-bin/php", "validsubdomainnames": "*", "extra": 42 }'::jsonb);
|
||||||
end; $$;
|
end; $$;
|
||||||
--//
|
--//
|
||||||
|
|
||||||
|
@ -130,17 +130,19 @@ databaseChangeLog:
|
|||||||
- include:
|
- include:
|
||||||
file: db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql
|
file: db/changelog/5-hs-office/512-coopassets/5128-hs-office-coopassets-test-data.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/6-hs-booking/610-booking-project/6100-hs-booking-project.sql
|
file: db/changelog/6-hs-booking/610-booking-debitor/6100-hs-booking-debitor.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/6-hs-booking/610-booking-project/6103-hs-booking-project-rbac.sql
|
file: db/changelog/6-hs-booking/620-booking-project/6200-hs-booking-project.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/6-hs-booking/610-booking-project/6108-hs-booking-project-test-data.sql
|
file: db/changelog/6-hs-booking/620-booking-project/6203-hs-booking-project-rbac.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/6-hs-booking/620-booking-item/6200-hs-booking-item.sql
|
file: db/changelog/6-hs-booking/620-booking-project/6208-hs-booking-project-test-data.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/6-hs-booking/620-booking-item/6203-hs-booking-item-rbac.sql
|
file: db/changelog/6-hs-booking/630-booking-item/6200-hs-booking-item.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/6-hs-booking/620-booking-item/6208-hs-booking-item-test-data.sql
|
file: db/changelog/6-hs-booking/630-booking-item/6203-hs-booking-item-rbac.sql
|
||||||
|
- include:
|
||||||
|
file: db/changelog/6-hs-booking/630-booking-item/6208-hs-booking-item-test-data.sql
|
||||||
- include:
|
- include:
|
||||||
file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql
|
file: db/changelog/7-hs-hosting/701-hosting-asset/7010-hs-hosting-asset.sql
|
||||||
- include:
|
- include:
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.booking.debitor;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class HsBookingDebitorEntityTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toStringContainsDebitorNumberAndDefaultPrefix() {
|
||||||
|
final var given = HsBookingDebitorEntity.builder()
|
||||||
|
.debitorNumber(1234567)
|
||||||
|
.defaultPrefix("som")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final var result = given.toString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("booking-debitor(D-1234567: som)");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toShortStringContainsDefaultPrefix() {
|
||||||
|
final var given = HsBookingDebitorEntity.builder()
|
||||||
|
.debitorNumber(1234567)
|
||||||
|
.defaultPrefix("som")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
final var result = given.toShortString();
|
||||||
|
|
||||||
|
assertThat(result).isEqualTo("D-1234567");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package net.hostsharing.hsadminng.hs.booking.debitor;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class TestHsBookingDebitor {
|
||||||
|
|
||||||
|
public static final HsBookingDebitorEntity TEST_BOOKING_DEBITOR = HsBookingDebitorEntity.builder()
|
||||||
|
.debitorNumber(1234500)
|
||||||
|
.defaultPrefix("abc")
|
||||||
|
.build();
|
||||||
|
}
|
@ -6,7 +6,6 @@ import io.restassured.http.ContentType;
|
|||||||
import net.hostsharing.hsadminng.HsadminNgApplication;
|
import net.hostsharing.hsadminng.HsadminNgApplication;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
|
||||||
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;
|
||||||
@ -17,8 +16,6 @@ import org.springframework.boot.test.context.SpringBootTest;
|
|||||||
import org.springframework.boot.test.web.server.LocalServerPort;
|
import org.springframework.boot.test.web.server.LocalServerPort;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
|
||||||
import jakarta.persistence.PersistenceContext;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -53,9 +50,6 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
|
|
||||||
@PersistenceContext
|
|
||||||
EntityManager em;
|
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class ListBookingItems {
|
class ListBookingItems {
|
||||||
|
|
||||||
@ -180,10 +174,10 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Test
|
@Test
|
||||||
void globalAdmin_canGetArbitraryBookingItem() {
|
void globalAdmin_canGetArbitraryBookingItem() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
final var givenBookingItemUuid = bookingItemRepo.findByCaption("some ManagedWebspace").stream()
|
||||||
.filter(bi -> belongsToDebitorNumber(bi, 1000111))
|
.filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "fir"))
|
||||||
.filter(item -> item.getCaption().equals("some ManagedWebspace"))
|
.map(HsBookingItemEntity::getUuid)
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -213,8 +207,8 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Test
|
@Test
|
||||||
void normalUser_canNotGetUnrelatedBookingItem() {
|
void normalUser_canNotGetUnrelatedBookingItem() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedServer").stream()
|
||||||
.filter(bi -> belongsToDebitorNumber(bi, 1000212))
|
.filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "sec"))
|
||||||
.map(HsBookingItemEntity::getUuid)
|
.map(HsBookingItemEntity::getUuid)
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
@ -229,16 +223,18 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void debitorAgentUser_canGetRelatedBookingItem() {
|
// TODO.impl: For unknown reason, this test fails in about 50%, not finding the uuid (404), maybe no SELECT permission?
|
||||||
|
void projectAdmin_canGetRelatedBookingItem() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItemUuid = bookingItemRepo.findAll().stream()
|
final var givenBookingItemUuid = bookingItemRepo.findByCaption("separate ManagedServer").stream()
|
||||||
.filter(bi -> belongsToDebitorNumber(bi, 1000313))
|
.filter(bi -> belongsToDebitorWithDefaultPrefix(bi, "thi"))
|
||||||
.filter(item -> item.getCaption().equals("separate ManagedServer"))
|
.map(HsBookingItemEntity::getUuid)
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "person-TuckerJack@example.com")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
|
.header("assumed-roles", "hs_booking_project#D-1000313-D-1000313defaultproject:ADMIN")
|
||||||
.port(port)
|
.port(port)
|
||||||
.when()
|
.when()
|
||||||
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
.get("http://localhost/api/hs/booking/items/" + givenBookingItemUuid)
|
||||||
@ -261,12 +257,11 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean belongsToDebitorNumber(final HsBookingItemEntity bi, final int i) {
|
private static boolean belongsToDebitorWithDefaultPrefix(final HsBookingItemEntity bi, final String defaultPrefix) {
|
||||||
return ofNullable(bi)
|
return ofNullable(bi)
|
||||||
.map(HsBookingItemEntity::getProject)
|
.map(HsBookingItemEntity::getProject)
|
||||||
.map(HsBookingProjectEntity::getDebitor)
|
.map(HsBookingProjectEntity::getDebitor)
|
||||||
.map(HsOfficeDebitorEntity::getDebitorNumber)
|
.map(bd -> bd.getDefaultPrefix().equals(defaultPrefix))
|
||||||
.filter(debitorNumber -> debitorNumber == i)
|
|
||||||
.isPresent();
|
.isPresent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,7 +312,7 @@ class HsBookingItemControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get()
|
assertThat(bookingItemRepo.findByUuid(givenBookingItem.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getProject().getDebitor().toString()).isEqualTo("debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), 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");
|
||||||
assertThat(mandate.getValidTo()).isEqualTo("2022-12-31");
|
assertThat(mandate.getValidTo()).isEqualTo("2022-12-31");
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,14 +29,14 @@ class HsBookingItemEntityUnitTest {
|
|||||||
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
||||||
final var result = givenBookingItem.toString();
|
final var result = givenBookingItem.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("HsBookingItemEntity(D-1000100:test project, CLOUD_SERVER, [2020-01-01,2031-01-01), some caption, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })");
|
assertThat(result).isEqualTo("HsBookingItemEntity(D-1234500:test project, CLOUD_SERVER, [2020-01-01,2031-01-01), some caption, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
||||||
final var result = givenBookingItem.toShortString();
|
final var result = givenBookingItem.toShortString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("D-1000100:test project:some caption");
|
assertThat(result).isEqualTo("D-1234500:test project:some caption");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -174,8 +174,8 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
|||||||
// then
|
// then
|
||||||
allTheseBookingItemsAreReturned(
|
allTheseBookingItemsAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
|
||||||
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })",
|
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_WEBSPACE, [2022-10-01,), some ManagedWebspace, { Daemons: 2, Multi: 4, SDD: 512, Traffic: 12 })",
|
||||||
|
"HsBookingItemEntity(D-1000212:D-1000212 default project, MANAGED_SERVER, [2022-10-01,), separate ManagedServer, { CPUs: 2, RAM: 8, SDD: 512, Traffic: 42 })",
|
||||||
"HsBookingItemEntity(D-1000212:D-1000212 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
"HsBookingItemEntity(D-1000212:D-1000212 default project, PRIVATE_CLOUD, [2024-04-01,), some PrivateCloud, { CPUs: 10, HDD: 10240, SDD: 10240, Traffic: 42 })");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,8 +326,7 @@ class HsBookingItemRepositoryIntegrationTest extends ContextBasedTestWithCleanup
|
|||||||
private HsBookingItemEntity givenSomeTemporaryBookingItem(final String projectCaption) {
|
private HsBookingItemEntity givenSomeTemporaryBookingItem(final String projectCaption) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenProject = projectRepo.findAll().stream()
|
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
|
||||||
.filter(p -> p.getCaption().equals(projectCaption))
|
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
final var newBookingItem = HsBookingItemEntity.builder()
|
final var newBookingItem = HsBookingItemEntity.builder()
|
||||||
.project(givenProject)
|
.project(givenProject)
|
||||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.booking.project;
|
|||||||
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.office.debitor.HsOfficeDebitorRepository;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
||||||
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.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
@ -15,10 +15,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import jakarta.persistence.PersistenceContext;
|
import jakarta.persistence.PersistenceContext;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
|
||||||
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;
|
||||||
import static org.hamcrest.Matchers.matchesRegex;
|
import static org.hamcrest.Matchers.matchesRegex;
|
||||||
@ -40,7 +38,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
HsBookingProjectRepository projectRepo;
|
HsBookingProjectRepository projectRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeDebitorRepository debitorRepo;
|
HsBookingDebitorRepository debitorRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
JpaAttempt jpaAttempt;
|
JpaAttempt jpaAttempt;
|
||||||
@ -56,7 +54,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
|
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
|
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).stream()
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow();
|
.orElseThrow();
|
||||||
|
|
||||||
@ -87,7 +85,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
void globalAdmin_canAddBookingProject() {
|
void globalAdmin_canAddBookingProject() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
|
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).stream()
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow();
|
.orElseThrow();
|
||||||
|
|
||||||
@ -128,8 +126,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.findAll().stream()
|
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000111 default project").stream()
|
||||||
.filter(project -> project.getDebitor().getDebitorNumber() == 1000111)
|
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
@ -151,8 +148,7 @@ 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.findAll().stream()
|
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000212 default project").stream()
|
||||||
.filter(project -> project.getDebitor().getDebitorNumber() == 1000212)
|
|
||||||
.map(HsBookingProjectEntity::getUuid)
|
.map(HsBookingProjectEntity::getUuid)
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
@ -169,8 +165,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
@Test
|
@Test
|
||||||
void debitorAgentUser_canGetRelatedBookingProject() {
|
void debitorAgentUser_canGetRelatedBookingProject() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingProjectUuid = bookingProjectRepo.findAll().stream()
|
final var givenBookingProjectUuid = bookingProjectRepo.findByCaption("D-1000313 default project").stream()
|
||||||
.filter(project -> project.getDebitor().getDebitorNumber() == 1000313)
|
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
@ -223,7 +218,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get()
|
assertThat(bookingProjectRepo.findByUuid(givenBookingProject.getUuid())).isPresent().get()
|
||||||
.matches(mandate -> {
|
.matches(mandate -> {
|
||||||
assertThat(mandate.getDebitor().toString()).isEqualTo("debitor(D-1000111: rel(anchor='LP First GmbH', type='DEBITOR', holder='LP First GmbH'), fir)");
|
assertThat(mandate.getDebitor().toString()).isEqualTo("booking-debitor(D-1000111: fir)");
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -272,7 +267,7 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
private HsBookingProjectEntity givenSomeBookingProject(final int debitorNumber, final String caption) {
|
private HsBookingProjectEntity 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.findDebitorByDebitorNumber(debitorNumber).stream().findAny().orElseThrow();
|
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).stream().findAny().orElseThrow();
|
||||||
final var newBookingProject = HsBookingProjectEntity.builder()
|
final var newBookingProject = HsBookingProjectEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
.uuid(UUID.randomUUID())
|
||||||
.debitor(givenDebitor)
|
.debitor(givenDebitor)
|
||||||
@ -282,8 +277,4 @@ class HsBookingProjectControllerAcceptanceTest extends ContextBasedTestWithClean
|
|||||||
return bookingProjectRepo.save(newBookingProject);
|
return bookingProjectRepo.save(newBookingProject);
|
||||||
}).assertSuccessful().returnedValue();
|
}).assertSuccessful().returnedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map.Entry<String, Object> resource(final String key, final Object value) {
|
|
||||||
return entry(key, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import jakarta.persistence.EntityManager;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR;
|
import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR;
|
||||||
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
@ -46,7 +46,7 @@ class HsBookingProjectEntityPatcherUnitTest extends PatchUnitTestBase<
|
|||||||
protected HsBookingProjectEntity newInitialEntity() {
|
protected HsBookingProjectEntity newInitialEntity() {
|
||||||
final var entity = new HsBookingProjectEntity();
|
final var entity = new HsBookingProjectEntity();
|
||||||
entity.setUuid(INITIAL_BOOKING_PROJECT_UUID);
|
entity.setUuid(INITIAL_BOOKING_PROJECT_UUID);
|
||||||
entity.setDebitor(TEST_DEBITOR);
|
entity.setDebitor(TEST_BOOKING_DEBITOR);
|
||||||
entity.setCaption(INITIAL_CAPTION);
|
entity.setCaption(INITIAL_CAPTION);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ 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.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR;
|
import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR;
|
||||||
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()
|
final HsBookingProjectEntity givenBookingProject = HsBookingProjectEntity.builder()
|
||||||
.debitor(TEST_DEBITOR)
|
.debitor(TEST_BOOKING_DEBITOR)
|
||||||
.caption("some caption")
|
.caption("some caption")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@ -15,13 +15,13 @@ class HsBookingProjectEntityUnitTest {
|
|||||||
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
||||||
final var result = givenBookingProject.toString();
|
final var result = givenBookingProject.toString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("HsBookingProjectEntity(D-1000100, some caption)");
|
assertThat(result).isEqualTo("HsBookingProjectEntity(D-1234500, some caption)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
||||||
final var result = givenBookingProject.toShortString();
|
final var result = givenBookingProject.toShortString();
|
||||||
|
|
||||||
assertThat(result).isEqualTo("D-1000100:some caption");
|
assertThat(result).isEqualTo("D-1234500:some caption");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.hostsharing.hsadminng.hs.booking.project;
|
package net.hostsharing.hsadminng.hs.booking.project;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorRepository;
|
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorRepository;
|
||||||
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.rbac.test.Array;
|
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||||
@ -38,7 +38,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
HsBookingProjectRepository projectRepo;
|
HsBookingProjectRepository projectRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
HsOfficeDebitorRepository debitorRepo;
|
HsBookingDebitorRepository debitorRepo;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RawRbacRoleRepository rawRoleRepo;
|
RawRbacRoleRepository rawRoleRepo;
|
||||||
@ -63,7 +63,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var count = bookingProjectRepo.count();
|
final var count = bookingProjectRepo.count();
|
||||||
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0);
|
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = attempt(em, () -> {
|
final var result = attempt(em, () -> {
|
||||||
@ -92,7 +92,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
|
|
||||||
// when
|
// when
|
||||||
attempt(em, () -> {
|
attempt(em, () -> {
|
||||||
final var givenDebitor = debitorRepo.findDebitorByOptionalNameLike("First").get(0);
|
final var givenDebitor = debitorRepo.findByDebitorNumber(1000111).get(0);
|
||||||
final var newBookingProject = HsBookingProjectEntity.builder()
|
final var newBookingProject = HsBookingProjectEntity.builder()
|
||||||
.debitor(givenDebitor)
|
.debitor(givenDebitor)
|
||||||
.caption("some new booking project")
|
.caption("some new booking project")
|
||||||
@ -148,7 +148,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor() {
|
public void globalAdmin_withoutAssumedRole_canViewAllBookingProjectsOfArbitraryDebitor() {
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000212).stream()
|
final var debitorUuid = debitorRepo.findByDebitorNumber(1000212).stream()
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -164,7 +164,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
public void normalUser_canViewOnlyRelatedBookingProjects() {
|
public void normalUser_canViewOnlyRelatedBookingProjects() {
|
||||||
// given:
|
// given:
|
||||||
context("person-FirbySusan@example.com");
|
context("person-FirbySusan@example.com");
|
||||||
final var debitorUuid = debitorRepo.findDebitorByDebitorNumber(1000111).stream()
|
final var debitorUuid = debitorRepo.findByDebitorNumber(1000111).stream()
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
@ -298,7 +298,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
private HsBookingProjectEntity givenSomeTemporaryBookingProject(final int debitorNumber) {
|
private HsBookingProjectEntity givenSomeTemporaryBookingProject(final int debitorNumber) {
|
||||||
return jpaAttempt.transacted(() -> {
|
return jpaAttempt.transacted(() -> {
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenDebitor = debitorRepo.findDebitorByDebitorNumber(debitorNumber).get(0);
|
final var givenDebitor = debitorRepo.findByDebitorNumber(debitorNumber).get(0);
|
||||||
final var newBookingProject = HsBookingProjectEntity.builder()
|
final var newBookingProject = HsBookingProjectEntity.builder()
|
||||||
.debitor(givenDebitor)
|
.debitor(givenDebitor)
|
||||||
.caption("some temp project")
|
.caption("some temp project")
|
||||||
@ -312,7 +312,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
final List<HsBookingProjectEntity> actualResult,
|
final List<HsBookingProjectEntity> actualResult,
|
||||||
final String... bookingProjectNames) {
|
final String... bookingProjectNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(bookingProjectEntity -> bookingProjectEntity.toString())
|
.extracting(HsBookingProjectEntity::toString)
|
||||||
.containsExactlyInAnyOrder(bookingProjectNames);
|
.containsExactlyInAnyOrder(bookingProjectNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +320,7 @@ class HsBookingProjectRepositoryIntegrationTest extends ContextBasedTestWithClea
|
|||||||
final List<HsBookingProjectEntity> actualResult,
|
final List<HsBookingProjectEntity> actualResult,
|
||||||
final String... bookingProjectNames) {
|
final String... bookingProjectNames) {
|
||||||
assertThat(actualResult)
|
assertThat(actualResult)
|
||||||
.extracting(bookingProjectEntity -> bookingProjectEntity.toString())
|
.extracting(HsBookingProjectEntity::toString)
|
||||||
.contains(bookingProjectNames);
|
.contains(bookingProjectNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,14 @@ package net.hostsharing.hsadminng.hs.booking.project;
|
|||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
import static net.hostsharing.hsadminng.hs.office.debitor.TestHsOfficeDebitor.TEST_DEBITOR;
|
import static net.hostsharing.hsadminng.hs.booking.debitor.TestHsBookingDebitor.TEST_BOOKING_DEBITOR;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class TestHsBookingProject {
|
public class TestHsBookingProject {
|
||||||
|
|
||||||
|
|
||||||
public static final HsBookingProjectEntity TEST_PROJECT = HsBookingProjectEntity.builder()
|
public static final HsBookingProjectEntity TEST_PROJECT = HsBookingProjectEntity.builder()
|
||||||
.debitor(TEST_DEBITOR)
|
.debitor(TEST_BOOKING_DEBITOR)
|
||||||
.caption("test project")
|
.caption("test project")
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import io.restassured.http.ContentType;
|
|||||||
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.HsBookingItemEntity;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
||||||
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;
|
||||||
@ -21,7 +20,6 @@ import java.util.Map;
|
|||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
import static java.util.Optional.ofNullable;
|
|
||||||
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 net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
|
import static net.hostsharing.hsadminng.rbac.test.JsonMatcher.lenientlyEquals;
|
||||||
@ -61,8 +59,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
|
|
||||||
// given
|
// given
|
||||||
context("superuser-alex@hostsharing.net");
|
context("superuser-alex@hostsharing.net");
|
||||||
final var givenProject = projectRepo.findAll().stream()
|
final var givenProject = projectRepo.findByCaption("D-1000111 default project").stream()
|
||||||
.filter(p -> p.getCaption().equals("D-1000111 default project"))
|
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
@ -81,9 +78,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"identifier": "sec01",
|
"identifier": "sec01",
|
||||||
"caption": "some Webspace",
|
"caption": "some Webspace",
|
||||||
"config": {
|
"config": {
|
||||||
"HDD": 2048,
|
|
||||||
"RAM": 1,
|
|
||||||
"SDD": 512,
|
|
||||||
"extra": 42
|
"extra": 42
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -92,9 +86,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"identifier": "fir01",
|
"identifier": "fir01",
|
||||||
"caption": "some Webspace",
|
"caption": "some Webspace",
|
||||||
"config": {
|
"config": {
|
||||||
"HDD": 2048,
|
|
||||||
"RAM": 1,
|
|
||||||
"SDD": 512,
|
|
||||||
"extra": 42
|
"extra": 42
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -103,9 +94,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"identifier": "thi01",
|
"identifier": "thi01",
|
||||||
"caption": "some Webspace",
|
"caption": "some Webspace",
|
||||||
"config": {
|
"config": {
|
||||||
"HDD": 2048,
|
|
||||||
"RAM": 1,
|
|
||||||
"SDD": 512,
|
|
||||||
"extra": 42
|
"extra": 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,18 +124,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"identifier": "vm1011",
|
"identifier": "vm1011",
|
||||||
"caption": "some ManagedServer",
|
"caption": "some ManagedServer",
|
||||||
"config": {
|
"config": {
|
||||||
"CPU": 2,
|
|
||||||
"SDD": 512,
|
|
||||||
"extra": 42
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "MANAGED_SERVER",
|
|
||||||
"identifier": "vm1013",
|
|
||||||
"caption": "some ManagedServer",
|
|
||||||
"config": {
|
|
||||||
"CPU": 2,
|
|
||||||
"SDD": 512,
|
|
||||||
"extra": 42
|
"extra": 42
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -156,8 +132,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"identifier": "vm1012",
|
"identifier": "vm1012",
|
||||||
"caption": "some ManagedServer",
|
"caption": "some ManagedServer",
|
||||||
"config": {
|
"config": {
|
||||||
"CPU": 2,
|
"extra": 42
|
||||||
"SDD": 512,
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "MANAGED_SERVER",
|
||||||
|
"identifier": "vm1013",
|
||||||
|
"caption": "some ManagedServer",
|
||||||
|
"config": {
|
||||||
"extra": 42
|
"extra": 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,7 +168,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"identifier": "vm1400",
|
"identifier": "vm1400",
|
||||||
"caption": "some new ManagedServer",
|
"caption": "some new ManagedServer",
|
||||||
"config": { "CPUs": 2, "RAM": 100, "SSD": 300, "Traffic": 250 }
|
"config": { "monit_max_ssd_usage": 80, "monit_max_cpu_usage": 90, "monit_max_ram_usage": 70 }
|
||||||
}
|
}
|
||||||
""".formatted(givenBookingItem.getUuid()))
|
""".formatted(givenBookingItem.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -200,7 +182,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"identifier": "vm1400",
|
"identifier": "vm1400",
|
||||||
"caption": "some new ManagedServer",
|
"caption": "some new ManagedServer",
|
||||||
"config": { "CPUs": 2, "RAM": 100, "SSD": 300, "Traffic": 250 }
|
"config": { "monit_max_ssd_usage": 80, "monit_max_cpu_usage": 90, "monit_max_ram_usage": 70 }
|
||||||
}
|
}
|
||||||
"""))
|
"""))
|
||||||
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
||||||
@ -216,7 +198,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
void parentAssetAgent_canAddSubAsset() {
|
void parentAssetAgent_canAddSubAsset() {
|
||||||
|
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenParentAsset = givenParentAsset("D-1000111 default project", MANAGED_SERVER);
|
final var givenParentAsset = givenParentAsset(MANAGED_SERVER, "vm1011");
|
||||||
|
|
||||||
context.define("person-FirbySusan@example.com");
|
context.define("person-FirbySusan@example.com");
|
||||||
|
|
||||||
@ -231,7 +213,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"type": "MANAGED_WEBSPACE",
|
"type": "MANAGED_WEBSPACE",
|
||||||
"identifier": "fir90",
|
"identifier": "fir90",
|
||||||
"caption": "some new ManagedWebspace in client's ManagedServer",
|
"caption": "some new ManagedWebspace in client's ManagedServer",
|
||||||
"config": { "SSD": 100, "Traffic": 250 }
|
"config": {}
|
||||||
}
|
}
|
||||||
""".formatted(givenParentAsset.getUuid()))
|
""".formatted(givenParentAsset.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -245,7 +227,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"type": "MANAGED_WEBSPACE",
|
"type": "MANAGED_WEBSPACE",
|
||||||
"identifier": "fir90",
|
"identifier": "fir90",
|
||||||
"caption": "some new ManagedWebspace in client's ManagedServer",
|
"caption": "some new ManagedWebspace in client's ManagedServer",
|
||||||
"config": { "SSD": 100, "Traffic": 250 }
|
"config": {}
|
||||||
}
|
}
|
||||||
"""))
|
"""))
|
||||||
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
.header("Location", matchesRegex("http://localhost:[1-9][0-9]*/api/hs/hosting/assets/[^/]*"))
|
||||||
@ -263,7 +245,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenBookingItem = givenBookingItem("D-1000111 default project", "some PrivateCloud");
|
final var givenBookingItem = givenBookingItem("D-1000111 default project", "some PrivateCloud");
|
||||||
|
|
||||||
final var location = RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
.header("current-user", "superuser-alex@hostsharing.net")
|
.header("current-user", "superuser-alex@hostsharing.net")
|
||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
@ -273,7 +255,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"type": "MANAGED_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"identifier": "vm1400",
|
"identifier": "vm1400",
|
||||||
"caption": "some new ManagedServer",
|
"caption": "some new ManagedServer",
|
||||||
"config": { "CPUs": 0, "extra": 42 }
|
"config": { "monit_max_ssd_usage": 0, "monit_max_cpu_usage": 101, "extra": 42 }
|
||||||
}
|
}
|
||||||
""".formatted(givenBookingItem.getUuid()))
|
""".formatted(givenBookingItem.getUuid()))
|
||||||
.port(port)
|
.port(port)
|
||||||
@ -285,7 +267,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"statusPhrase": "Bad Request",
|
"statusPhrase": "Bad Request",
|
||||||
"message": "['config.extra' is not expected but is set to '42', 'config.CPUs' is expected to be >= 1 but is 0, 'config.RAM' is required but missing, 'config.SSD' is required but missing, 'config.Traffic' is required but missing]"
|
"message": "['config.extra' is not expected but is set to '42', 'config.monit_max_ssd_usage' is expected to be >= 10 but is 0, 'config.monit_max_cpu_usage' is expected to be <= 100 but is 101, 'config.monit_max_ram_usage' is required but missing]"
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
}
|
}
|
||||||
@ -297,9 +279,8 @@ 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.findAll().stream()
|
final var givenAssetUuid = assetRepo.findByIdentifier("vm1011").stream()
|
||||||
.filter(bi -> bi.getBookingItem().getProject().getDebitor().getDebitorNumber() == 1000111)
|
.filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000111 default project"))
|
||||||
.filter(item -> item.getCaption().equals("some ManagedServer"))
|
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
@ -315,8 +296,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
{
|
{
|
||||||
"caption": "some ManagedServer",
|
"caption": "some ManagedServer",
|
||||||
"config": {
|
"config": {
|
||||||
"CPU": 2,
|
|
||||||
"SDD": 512,
|
|
||||||
"extra": 42
|
"extra": 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -326,8 +305,8 @@ 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.findAll().stream()
|
final var givenAssetUuid = assetRepo.findByIdentifier("vm1012").stream()
|
||||||
.filter(bi -> bi.getBookingItem().getProject().getDebitor().getDebitorNumber() == 1000212)
|
.filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000212 default project"))
|
||||||
.map(HsHostingAssetEntity::getUuid)
|
.map(HsHostingAssetEntity::getUuid)
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
|
|
||||||
@ -344,9 +323,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Test
|
@Test
|
||||||
void debitorAgentUser_canGetRelatedAsset() {
|
void debitorAgentUser_canGetRelatedAsset() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAssetUuid = assetRepo.findAll().stream()
|
final var givenAssetUuid = assetRepo.findByIdentifier("vm1013").stream()
|
||||||
.filter(bi -> bi.getBookingItem().getProject().getDebitor().getDebitorNumber() == 1000313)
|
.filter(bi -> bi.getBookingItem().getProject().getCaption().equals("D-1000313 default project"))
|
||||||
.filter(bi -> bi.getCaption().equals("some ManagedServer"))
|
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
@ -363,8 +341,6 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
"identifier": "vm1013",
|
"identifier": "vm1013",
|
||||||
"caption": "some ManagedServer",
|
"caption": "some ManagedServer",
|
||||||
"config": {
|
"config": {
|
||||||
"CPU": 2,
|
|
||||||
"SDD": 512,
|
|
||||||
"extra": 42
|
"extra": 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,8 +354,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Test
|
@Test
|
||||||
void globalAdmin_canPatchAllUpdatablePropertiesOfAsset() {
|
void globalAdmin_canPatchAllUpdatablePropertiesOfAsset() {
|
||||||
|
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset("2001", CLOUD_SERVER,
|
final var givenAsset = givenSomeTemporaryHostingAsset("2001", MANAGED_SERVER,
|
||||||
config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000));
|
config("monit_max_ssd_usage", 80), config("monit_max_hdd_usage", 90), config("monit_max_cpu_usage", 90), config("monit_max_ram_usage", 70));
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -388,9 +364,9 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.body("""
|
.body("""
|
||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"CPUs": 2,
|
"monit_max_ssd_usage": 85,
|
||||||
"HDD": null,
|
"monit_max_hdd_usage": null,
|
||||||
"SSD": 250
|
"monit_min_free_ssd": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
@ -402,13 +378,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
.contentType(ContentType.JSON)
|
.contentType(ContentType.JSON)
|
||||||
.body("", lenientlyEquals("""
|
.body("", lenientlyEquals("""
|
||||||
{
|
{
|
||||||
"type": "CLOUD_SERVER",
|
"type": "MANAGED_SERVER",
|
||||||
"identifier": "vm2001",
|
"identifier": "vm2001",
|
||||||
"caption": "some test-asset",
|
"caption": "some test-asset",
|
||||||
"config": {
|
"config": {
|
||||||
"CPUs": 2,
|
"monit_max_cpu_usage": 90,
|
||||||
"RAM": 100,
|
"monit_max_ram_usage": 70,
|
||||||
"SSD": 250
|
"monit_max_ssd_usage": 85,
|
||||||
|
"monit_min_free_ssd": 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""")); // @formatter:on
|
""")); // @formatter:on
|
||||||
@ -417,7 +394,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
|
assertThat(assetRepo.findByUuid(givenAsset.getUuid())).isPresent().get()
|
||||||
.matches(asset -> {
|
.matches(asset -> {
|
||||||
assertThat(asset.toString()).isEqualTo("HsHostingAssetEntity(CLOUD_SERVER, vm2001, some test-asset, D-1000111:D-1000111 default project:test CloudServer, { CPUs: 2, RAM: 100, SSD: 250, Traffic: 2000 })");
|
assertThat(asset.toString()).isEqualTo(
|
||||||
|
"HsHostingAssetEntity(MANAGED_SERVER, vm2001, some test-asset, D-1000111:D-1000111 default project:some ManagedServer, { monit_max_cpu_usage: 90, monit_max_ram_usage: 70, monit_max_ssd_usage: 85, monit_min_free_ssd: 5 })");
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -429,8 +407,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Test
|
@Test
|
||||||
void globalAdmin_canDeleteArbitraryAsset() {
|
void globalAdmin_canDeleteArbitraryAsset() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset("2002", CLOUD_SERVER,
|
final var givenAsset = givenSomeTemporaryHostingAsset("1002", MANAGED_SERVER,
|
||||||
config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000));
|
config("monit_max_ssd_usage", 80), config("monit_max_hdd_usage", 90), config("monit_max_cpu_usage", 90), config("monit_max_ram_usage", 70));
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -448,8 +426,8 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
@Test
|
@Test
|
||||||
void normalUser_canNotDeleteUnrelatedAsset() {
|
void normalUser_canNotDeleteUnrelatedAsset() {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var givenAsset = givenSomeTemporaryHostingAsset("2003", CLOUD_SERVER,
|
final var givenAsset = givenSomeTemporaryHostingAsset("1003", MANAGED_SERVER,
|
||||||
config("CPUs", 4), config("RAM", 100), config("HDD", 100), config("Traffic", 2000));
|
config("monit_max_ssd_usage", 80), config("monit_max_hdd_usage", 90), config("monit_max_cpu_usage", 90), config("monit_max_ram_usage", 70));
|
||||||
|
|
||||||
RestAssured // @formatter:off
|
RestAssured // @formatter:off
|
||||||
.given()
|
.given()
|
||||||
@ -466,22 +444,14 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
}
|
}
|
||||||
|
|
||||||
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
|
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
|
||||||
return bookingItemRepo.findAll().stream()
|
return bookingItemRepo.findByCaption(bookingItemCaption).stream()
|
||||||
.filter(a -> ofNullable(a)
|
.filter(bi -> bi.getRelatedProject().getCaption().contains(projectCaption))
|
||||||
.filter(bi -> bi.getCaption().equals(bookingItemCaption))
|
|
||||||
.isPresent())
|
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
HsHostingAssetEntity givenParentAsset(final String projectCaption, final HsHostingAssetType assetType) {
|
HsHostingAssetEntity givenParentAsset(final HsHostingAssetType assetType, final String assetIdentifier) {
|
||||||
final var givenAsset = assetRepo.findAll().stream()
|
final var givenAsset = assetRepo.findByIdentifier(assetIdentifier).stream()
|
||||||
.filter(a -> a.getType() == assetType)
|
.filter(a -> a.getType() == assetType)
|
||||||
.filter(a -> ofNullable(a)
|
|
||||||
.map(HsHostingAssetEntity::getBookingItem)
|
|
||||||
.map(HsBookingItemEntity::getProject)
|
|
||||||
.map(HsBookingProjectEntity::getCaption)
|
|
||||||
.filter(c -> c.equals(projectCaption))
|
|
||||||
.isPresent())
|
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
return givenAsset;
|
return givenAsset;
|
||||||
}
|
}
|
||||||
@ -494,7 +464,7 @@ class HsHostingAssetControllerAcceptanceTest extends ContextBasedTestWithCleanup
|
|||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var newAsset = HsHostingAssetEntity.builder()
|
final var newAsset = HsHostingAssetEntity.builder()
|
||||||
.uuid(UUID.randomUUID())
|
.uuid(UUID.randomUUID())
|
||||||
.bookingItem(givenBookingItem("D-1000111 default project", "test CloudServer"))
|
.bookingItem(givenBookingItem("D-1000111 default project", "some ManagedServer"))
|
||||||
.type(hostingAssetType)
|
.type(hostingAssetType)
|
||||||
.identifier("vm" + identifierSuffix)
|
.identifier("vm" + identifierSuffix)
|
||||||
.caption("some test-asset")
|
.caption("some test-asset")
|
||||||
|
@ -20,7 +20,7 @@ class HsHostingAssetEntityUnitTest {
|
|||||||
entry("SSD-storage", 512),
|
entry("SSD-storage", 512),
|
||||||
entry("HDD-storage", 2048)))
|
entry("HDD-storage", 2048)))
|
||||||
.build();
|
.build();
|
||||||
final HsHostingAssetEntity givenServer = HsHostingAssetEntity.builder()
|
final HsHostingAssetEntity givenWebspace = HsHostingAssetEntity.builder()
|
||||||
.bookingItem(TEST_BOOKING_ITEM)
|
.bookingItem(TEST_BOOKING_ITEM)
|
||||||
.type(HsHostingAssetType.MANAGED_WEBSPACE)
|
.type(HsHostingAssetType.MANAGED_WEBSPACE)
|
||||||
.parentAsset(givenParentAsset)
|
.parentAsset(givenParentAsset)
|
||||||
@ -31,19 +31,47 @@ 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()
|
||||||
|
.type(HsHostingAssetType.UNIX_USER)
|
||||||
|
.parentAsset(givenWebspace)
|
||||||
|
.identifier("xyz00-web")
|
||||||
|
.caption("some unix-user")
|
||||||
|
.config(Map.ofEntries(
|
||||||
|
entry("SSD-soft-quota", 128),
|
||||||
|
entry("SSD-hard-quota", 256),
|
||||||
|
entry("HDD-soft-quota", 256),
|
||||||
|
entry("HDD-hard-quota", 512)))
|
||||||
|
.build();
|
||||||
|
final HsHostingAssetEntity givenDomainHttpSetup = HsHostingAssetEntity.builder()
|
||||||
|
.type(HsHostingAssetType.DOMAIN_HTTP_SETUP)
|
||||||
|
.parentAsset(givenWebspace)
|
||||||
|
.identifier("example.org")
|
||||||
|
.assignedToAsset(givenUnixUser)
|
||||||
|
.caption("some domain setup")
|
||||||
|
.config(Map.ofEntries(
|
||||||
|
entry("option-htdocsfallback", true),
|
||||||
|
entry("use-fcgiphpbin", "/usr/lib/cgi-bin/php"),
|
||||||
|
entry("validsubdomainnames", "*")))
|
||||||
|
.build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
void toStringContainsAllPropertiesAndResourcesSortedByKey() {
|
||||||
final var result = givenServer.toString();
|
|
||||||
|
|
||||||
assertThat(result).isEqualTo(
|
assertThat(givenWebspace.toString()).isEqualTo(
|
||||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, xyz00, some managed webspace, MANAGED_SERVER:vm1234, D-1000100:test project:test booking item, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })");
|
"HsHostingAssetEntity(MANAGED_WEBSPACE, xyz00, some managed webspace, MANAGED_SERVER:vm1234, D-1234500:test project:test booking item, { CPUs: 2, HDD-storage: 2048, SSD-storage: 512 })");
|
||||||
|
|
||||||
|
assertThat(givenUnixUser.toString()).isEqualTo(
|
||||||
|
"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 })");
|
||||||
|
|
||||||
|
assertThat(givenDomainHttpSetup.toString()).isEqualTo(
|
||||||
|
"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: * })");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
void toShortStringContainsOnlyMemberNumberAndCaption() {
|
||||||
final var result = givenServer.toShortString();
|
|
||||||
|
|
||||||
assertThat(result).isEqualTo("MANAGED_WEBSPACE:xyz00");
|
assertThat(givenWebspace.toShortString()).isEqualTo("MANAGED_WEBSPACE:xyz00");
|
||||||
|
assertThat(givenUnixUser.toShortString()).isEqualTo("UNIX_USER:xyz00-web");
|
||||||
|
assertThat(givenDomainHttpSetup.toShortString()).isEqualTo("DOMAIN_HTTP_SETUP:example.org");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,48 +54,57 @@ class HsHostingAssetPropsControllerAcceptanceTest {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"propertyName": "CPUs",
|
"propertyName": "monit_min_free_ssd",
|
||||||
"required": true,
|
"required": false,
|
||||||
"unit": null,
|
"unit": null,
|
||||||
"min": 1,
|
"min": 1,
|
||||||
"max": 32,
|
|
||||||
"step": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"propertyName": "RAM",
|
|
||||||
"required": true,
|
|
||||||
"unit": "GB",
|
|
||||||
"min": 1,
|
|
||||||
"max": 128,
|
|
||||||
"step": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"propertyName": "SSD",
|
|
||||||
"required": true,
|
|
||||||
"unit": "GB",
|
|
||||||
"min": 25,
|
|
||||||
"max": 1000,
|
"max": 1000,
|
||||||
"step": 25
|
"step": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"propertyName": "HDD",
|
"propertyName": "monit_min_free_hdd",
|
||||||
"required": false,
|
"required": false,
|
||||||
"unit": "GB",
|
"unit": null,
|
||||||
"min": 0,
|
"min": 1,
|
||||||
"max": 4000,
|
"max": 4000,
|
||||||
"step": 250
|
"step": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"propertyName": "Traffic",
|
"propertyName": "monit_max_ssd_usage",
|
||||||
"required": true,
|
"required": true,
|
||||||
"unit": "GB",
|
"unit": "%",
|
||||||
"min": 250,
|
"min": 10,
|
||||||
"max": 10000,
|
"max": 100,
|
||||||
"step": 250
|
"step": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"propertyName": "monit_max_hdd_usage",
|
||||||
|
"required": false,
|
||||||
|
"unit": "%",
|
||||||
|
"min": 10,
|
||||||
|
"max": 100,
|
||||||
|
"step": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"propertyName": "monit_max_cpu_usage",
|
||||||
|
"required": true,
|
||||||
|
"unit": "%",
|
||||||
|
"min": 10,
|
||||||
|
"max": 100,
|
||||||
|
"step": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"propertyName": "monit_max_ram_usage",
|
||||||
|
"required": true,
|
||||||
|
"unit": "%",
|
||||||
|
"min": 10,
|
||||||
|
"max": 100,
|
||||||
|
"step": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
"""));
|
"""));
|
||||||
|
@ -4,7 +4,6 @@ import net.hostsharing.hsadminng.context.Context;
|
|||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||||
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
|
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRepository;
|
||||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRepository;
|
||||||
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;
|
||||||
import net.hostsharing.hsadminng.rbac.test.Array;
|
import net.hostsharing.hsadminng.rbac.test.Array;
|
||||||
@ -48,9 +47,6 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
@Autowired
|
@Autowired
|
||||||
HsBookingProjectRepository projectRepo;
|
HsBookingProjectRepository projectRepo;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
HsOfficeDebitorRepository debitorRepo;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
RawRbacRoleRepository rawRoleRepo;
|
RawRbacRoleRepository rawRoleRepo;
|
||||||
|
|
||||||
@ -143,7 +139,6 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
"{ grant role:hs_hosting_asset#vm9000:AGENT to role:hs_hosting_asset#vm9000:ADMIN by system and assume }",
|
"{ grant role:hs_hosting_asset#vm9000:AGENT to role:hs_hosting_asset#vm9000:ADMIN by system and assume }",
|
||||||
|
|
||||||
// tenant
|
// tenant
|
||||||
"{ grant perm:hs_hosting_asset#vm9000:SELECT to role:hs_hosting_asset#vm9000:TENANT by system and assume }",
|
|
||||||
"{ grant role:hs_booking_item#somePrivateCloud:TENANT to role:hs_hosting_asset#vm9000:TENANT by system and assume }",
|
"{ grant role:hs_booking_item#somePrivateCloud:TENANT to role:hs_hosting_asset#vm9000:TENANT by system and assume }",
|
||||||
|
|
||||||
null));
|
null));
|
||||||
@ -169,17 +164,16 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
// then
|
// then
|
||||||
allTheseServersAreReturned(
|
allTheseServersAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(MANAGED_WEBSPACE, sec01, some Webspace, MANAGED_SERVER:vm1012, D-1000212:D-1000212 default project:separate ManagedServer, { extra: 42 })",
|
||||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { extra: 42 })",
|
||||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })");
|
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { extra: 42 })");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void normalUser_canViewOnlyRelatedAsset() {
|
public void normalUser_canViewOnlyRelatedAsset() {
|
||||||
// given:
|
// given:
|
||||||
context("person-FirbySusan@example.com");
|
context("person-FirbySusan@example.com");
|
||||||
final var projectUuid = projectRepo.findAll().stream()
|
final var projectUuid = projectRepo.findByCaption("D-1000111 default project").stream()
|
||||||
.filter(p -> p.getCaption().equals("D-1000111 default project"))
|
|
||||||
.findAny().orElseThrow().getUuid();
|
.findAny().orElseThrow().getUuid();
|
||||||
|
|
||||||
// when:
|
// when:
|
||||||
@ -188,9 +182,9 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
// then:
|
// then:
|
||||||
exactlyTheseAssetsAreReturned(
|
exactlyTheseAssetsAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(MANAGED_WEBSPACE, fir01, some Webspace, MANAGED_SERVER:vm1011, D-1000111:D-1000111 default project:separate ManagedServer, { extra: 42 })",
|
||||||
"HsHostingAssetEntity(MANAGED_SERVER, vm1011, some ManagedServer, D-1000111:D-1000111 default project:some PrivateCloud, { CPU: 2, SDD: 512, extra: 42 })",
|
"HsHostingAssetEntity(MANAGED_SERVER, vm1011, some ManagedServer, D-1000111:D-1000111 default project:some PrivateCloud, { extra: 42 })",
|
||||||
"HsHostingAssetEntity(CLOUD_SERVER, vm2011, another CloudServer, D-1000111:D-1000111 default project:some PrivateCloud, { CPU: 2, HDD: 1024, extra: 42 })");
|
"HsHostingAssetEntity(CLOUD_SERVER, vm2011, another CloudServer, D-1000111:D-1000111 default project:some PrivateCloud, { extra: 42 })");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -206,7 +200,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
// then
|
// then
|
||||||
allTheseServersAreReturned(
|
allTheseServersAreReturned(
|
||||||
result,
|
result,
|
||||||
"HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { HDD: 2048, RAM: 1, SDD: 512, extra: 42 })");
|
"HsHostingAssetEntity(MANAGED_WEBSPACE, thi01, some Webspace, MANAGED_SERVER:vm1013, D-1000313:D-1000313 default project:separate ManagedServer, { extra: 42 })");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -373,8 +367,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
}
|
}
|
||||||
|
|
||||||
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
|
HsBookingItemEntity givenBookingItem(final String projectCaption, final String bookingItemCaption) {
|
||||||
final var givenProject = projectRepo.findAll().stream()
|
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
|
||||||
.filter(p -> p.getCaption().equals(projectCaption))
|
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
return bookingItemRepo.findAllByProjectUuid(givenProject.getUuid()).stream()
|
return bookingItemRepo.findAllByProjectUuid(givenProject.getUuid()).stream()
|
||||||
.filter(i -> i.getCaption().equals(bookingItemCaption))
|
.filter(i -> i.getCaption().equals(bookingItemCaption))
|
||||||
@ -382,8 +375,7 @@ class HsHostingAssetRepositoryIntegrationTest extends ContextBasedTestWithCleanu
|
|||||||
}
|
}
|
||||||
|
|
||||||
HsHostingAssetEntity givenManagedServer(final String projectCaption, final HsHostingAssetType type) {
|
HsHostingAssetEntity givenManagedServer(final String projectCaption, final HsHostingAssetType type) {
|
||||||
final var givenProject = projectRepo.findAll().stream()
|
final var givenProject = projectRepo.findByCaption(projectCaption).stream()
|
||||||
.filter(p -> p.getCaption().equals(projectCaption))
|
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
return assetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream()
|
return assetRepo.findAllByCriteria(givenProject.getUuid(), null, type).stream()
|
||||||
.findAny().orElseThrow();
|
.findAny().orElseThrow();
|
||||||
|
@ -18,10 +18,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
|||||||
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
.type(CLOUD_SERVER)
|
.type(CLOUD_SERVER)
|
||||||
.config(Map.ofEntries(
|
.config(Map.ofEntries(
|
||||||
entry("RAM", 2000),
|
entry("RAM", 2000)
|
||||||
entry("SSD", 256),
|
|
||||||
entry("Traffic", "250"),
|
|
||||||
entry("SLA-Platform", "xxx")
|
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
final var validator = forType(cloudServerHostingAssetEntity.getType());
|
final var validator = forType(cloudServerHostingAssetEntity.getType());
|
||||||
@ -31,12 +28,7 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
|||||||
final var result = validator.validate(cloudServerHostingAssetEntity);
|
final var result = validator.validate(cloudServerHostingAssetEntity);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).containsExactlyInAnyOrder(
|
assertThat(result).containsExactly("'config.RAM' is not expected but is set to '2000'");
|
||||||
"'config.SLA-Platform' is not expected but is set to 'xxx'",
|
|
||||||
"'config.CPUs' is required but missing",
|
|
||||||
"'config.RAM' is expected to be <= 128 but is 2000",
|
|
||||||
"'config.SSD' is expected to be multiple of 25 but is 256",
|
|
||||||
"'config.Traffic' is expected to be of type class java.lang.Integer, but is of type 'String'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -45,11 +37,6 @@ class HsCloudServerHostingAssetValidatorUnitTest {
|
|||||||
final var validator = forType(CLOUD_SERVER);
|
final var validator = forType(CLOUD_SERVER);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(validator.properties()).map(Map::toString).containsExactlyInAnyOrder(
|
assertThat(validator.properties()).map(Map::toString).isEmpty();
|
||||||
"{type=integer, propertyName=CPUs, required=true, unit=null, min=1, max=32, step=null}",
|
|
||||||
"{type=integer, propertyName=RAM, required=true, unit=GB, min=1, max=128, step=null}",
|
|
||||||
"{type=integer, propertyName=SSD, required=true, unit=GB, min=25, max=1000, step=25}",
|
|
||||||
"{type=integer, propertyName=HDD, required=false, unit=GB, min=0, max=4000, step=250}",
|
|
||||||
"{type=integer, propertyName=Traffic, required=true, unit=GB, min=250, max=10000, step=250}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import jakarta.validation.ValidationException;
|
import jakarta.validation.ValidationException;
|
||||||
|
|
||||||
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.validators.HsHostingAssetEntityValidators.valid;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.validators.HsHostingAssetEntityValidators.valid;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||||
@ -15,19 +15,18 @@ class HsHostingAssetEntityValidatorsUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
void validThrowsException() {
|
void validThrowsException() {
|
||||||
// given
|
// given
|
||||||
final var cloudServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
final var managedServerHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
.type(CLOUD_SERVER)
|
.type(MANAGED_SERVER)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
final var result = catchThrowable( ()-> valid(cloudServerHostingAssetEntity) );
|
final var result = catchThrowable( ()-> valid(managedServerHostingAssetEntity) );
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).isInstanceOf(ValidationException.class)
|
assertThat(result).isInstanceOf(ValidationException.class)
|
||||||
.hasMessageContaining(
|
.hasMessageContaining(
|
||||||
"'config.CPUs' is required but missing",
|
"'config.monit_max_ssd_usage' is required but missing",
|
||||||
"'config.RAM' is required but missing",
|
"'config.monit_max_cpu_usage' is required but missing",
|
||||||
"'config.SSD' is required but missing",
|
"'config.monit_max_ram_usage' is required but missing");
|
||||||
"'config.Traffic' is required but missing");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,9 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
|||||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
.type(MANAGED_SERVER)
|
.type(MANAGED_SERVER)
|
||||||
.config(Map.ofEntries(
|
.config(Map.ofEntries(
|
||||||
entry("RAM", 2000),
|
entry("monit_max_hdd_usage", "90"),
|
||||||
entry("SSD", 256),
|
entry("monit_max_cpu_usage", 2),
|
||||||
entry("Traffic", "250"),
|
entry("monit_max_ram_usage", 101)
|
||||||
entry("SLA-Platform", "xxx")
|
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
final var validator = forType(mangedWebspaceHostingAssetEntity.getType());
|
final var validator = forType(mangedWebspaceHostingAssetEntity.getType());
|
||||||
@ -31,10 +30,9 @@ class HsManagedServerHostingAssetValidatorUnitTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThat(result).containsExactlyInAnyOrder(
|
assertThat(result).containsExactlyInAnyOrder(
|
||||||
"'config.SLA-Platform' is not expected but is set to 'xxx'",
|
"'config.monit_max_ssd_usage' is required but missing",
|
||||||
"'config.CPUs' is required but missing",
|
"'config.monit_max_hdd_usage' is expected to be of type class java.lang.Integer, but is of type 'String'",
|
||||||
"'config.RAM' is expected to be <= 128 but is 2000",
|
"'config.monit_max_cpu_usage' is expected to be >= 10 but is 2",
|
||||||
"'config.SSD' is expected to be multiple of 25 but is 256",
|
"'config.monit_max_ram_usage' is expected to be <= 100 but is 101");
|
||||||
"'config.Traffic' is expected to be of type class java.lang.Integer, but is of type 'String'");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static java.util.Collections.emptyMap;
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_SERVER;
|
||||||
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
import static net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetType.MANAGED_WEBSPACE;
|
||||||
@ -36,11 +35,6 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
|||||||
.type(MANAGED_WEBSPACE)
|
.type(MANAGED_WEBSPACE)
|
||||||
.parentAsset(mangedServerAssetEntity)
|
.parentAsset(mangedServerAssetEntity)
|
||||||
.identifier("xyz00")
|
.identifier("xyz00")
|
||||||
.config(Map.ofEntries(
|
|
||||||
entry("HDD", 0),
|
|
||||||
entry("SSD", 1),
|
|
||||||
entry("Traffic", 10)
|
|
||||||
))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -50,28 +44,6 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
|||||||
assertThat(result).containsExactly("'identifier' expected to match '^abc[0-9][0-9]$', but is 'xyz00'");
|
assertThat(result).containsExactly("'identifier' expected to match '^abc[0-9][0-9]$', but is 'xyz00'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void validatesMissingProperties() {
|
|
||||||
// given
|
|
||||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
|
||||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
|
||||||
.type(MANAGED_WEBSPACE)
|
|
||||||
.parentAsset(mangedServerAssetEntity)
|
|
||||||
.identifier("abc00")
|
|
||||||
.config(emptyMap())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var result = validator.validate(mangedWebspaceHostingAssetEntity);
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(result).containsExactlyInAnyOrder(
|
|
||||||
"'config.SSD' is required but missing",
|
|
||||||
"'config.Traffic' is required but missing"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void validatesUnknownProperties() {
|
void validatesUnknownProperties() {
|
||||||
// given
|
// given
|
||||||
@ -81,9 +53,6 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
|||||||
.parentAsset(mangedServerAssetEntity)
|
.parentAsset(mangedServerAssetEntity)
|
||||||
.identifier("abc00")
|
.identifier("abc00")
|
||||||
.config(Map.ofEntries(
|
.config(Map.ofEntries(
|
||||||
entry("HDD", 0),
|
|
||||||
entry("SSD", 1),
|
|
||||||
entry("Traffic", 10),
|
|
||||||
entry("unknown", "some value")
|
entry("unknown", "some value")
|
||||||
))
|
))
|
||||||
.build();
|
.build();
|
||||||
@ -96,18 +65,13 @@ class HsManagedWebspaceHostingAssetValidatorUnitTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void validatesValidProperties() {
|
void validatesValidEntity() {
|
||||||
// given
|
// given
|
||||||
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
final var validator = HsHostingAssetEntityValidators.forType(MANAGED_WEBSPACE);
|
||||||
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
final var mangedWebspaceHostingAssetEntity = HsHostingAssetEntity.builder()
|
||||||
.type(MANAGED_WEBSPACE)
|
.type(MANAGED_WEBSPACE)
|
||||||
.parentAsset(mangedServerAssetEntity)
|
.parentAsset(mangedServerAssetEntity)
|
||||||
.identifier("abc00")
|
.identifier("abc00")
|
||||||
.config(Map.ofEntries(
|
|
||||||
entry("HDD", 200),
|
|
||||||
entry("SSD", 25),
|
|
||||||
entry("Traffic", 250)
|
|
||||||
))
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
@ -745,7 +745,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
|||||||
jpaAttempt.transacted(() -> {
|
jpaAttempt.transacted(() -> {
|
||||||
context.define("superuser-alex@hostsharing.net");
|
context.define("superuser-alex@hostsharing.net");
|
||||||
final var count = em.createQuery(
|
final var count = em.createQuery(
|
||||||
"DELETE FROM HsOfficeDebitorEntity d WHERE d.debitorNumberSuffix >= " + LOWEST_TEMP_DEBITOR_SUFFIX)
|
"DELETE FROM HsBookingDebitorEntity d WHERE d.debitorNumberSuffix >= " + LOWEST_TEMP_DEBITOR_SUFFIX)
|
||||||
.executeUpdate();
|
.executeUpdate();
|
||||||
System.out.printf("deleted %d entities%n", count);
|
System.out.printf("deleted %d entities%n", count);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user