improve-performance-of-office-data-import #83
@ -121,8 +121,8 @@ WITH statements AS (
|
||||
SELECT * FROM pg_stat_statements pss
|
||||
)
|
||||
SELECT calls,
|
||||
total_exec_time::int/(60*1000) as total_exec_time_mins,
|
||||
mean_exec_time::int as mean_exec_time_millis,
|
||||
total_exec_time::int/(60*1000) as total_mins,
|
||||
mean_exec_time::int as mean_millis,
|
||||
query
|
||||
FROM statements
|
||||
WHERE calls > 100 AND shared_blks_hit > 0
|
||||
|
@ -15,7 +15,7 @@ import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.Type;
|
||||
@ -71,7 +71,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class HsBookingItemEntity implements Stringifyable, RbacObject<HsBookingItemEntity>, PropertiesProvider {
|
||||
public class HsBookingItemEntity implements Stringifyable, BaseEntity<HsBookingItemEntity>, PropertiesProvider {
|
||||
|
||||
private static Stringify<HsBookingItemEntity> stringify = stringify(HsBookingItemEntity.class)
|
||||
.withProp(HsBookingItemEntity::getProject)
|
||||
|
@ -3,10 +3,10 @@ package net.hostsharing.hsadminng.hs.booking.project;
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.hs.booking.debitor.HsBookingDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class HsBookingProjectEntity implements Stringifyable, RbacObject<HsBookingProjectEntity> {
|
||||
public class HsBookingProjectEntity implements Stringifyable, BaseEntity<HsBookingProjectEntity> {
|
||||
|
||||
private static Stringify<HsBookingProjectEntity> stringify = stringify(HsBookingProjectEntity.class)
|
||||
.withProp(HsBookingProjectEntity::getDebitor)
|
||||
@ -81,7 +81,7 @@ public class HsBookingProjectEntity implements Stringifyable, RbacObject<HsBooki
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
NOT_NULL)
|
||||
|
||||
.importEntityAlias("debitorRel", HsOfficeRelation.class, usingCase(DEBITOR),
|
||||
.importEntityAlias("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
|
||||
dependsOnColumn("debitorUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
|
@ -4,7 +4,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactBareEntity;
|
||||
import net.hostsharing.hsadminng.hs.validation.PropertiesProvider;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -16,7 +16,7 @@ import java.util.UUID;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
|
||||
public interface HsHostingAsset extends Stringifyable, RbacObject<HsHostingAsset>, PropertiesProvider {
|
||||
public interface HsHostingAsset extends Stringifyable, BaseEntity<HsHostingAsset>, PropertiesProvider {
|
||||
|
||||
Stringify<HsHostingAsset> stringify = stringify(HsHostingAsset.class)
|
||||
.withProp(HsHostingAsset::getType)
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@AllArgsConstructor
|
||||
@FieldNameConstants
|
||||
@DisplayName("BankAccount")
|
||||
public class HsOfficeBankAccountEntity implements RbacObject<HsOfficeBankAccountEntity>, Stringifyable {
|
||||
public class HsOfficeBankAccountEntity implements BaseEntity<HsOfficeBankAccountEntity>, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficeBankAccountEntity> toString = stringify(HsOfficeBankAccountEntity.class, "bankAccount")
|
||||
.withIdProp(HsOfficeBankAccountEntity::getIban)
|
||||
|
@ -11,7 +11,7 @@ import lombok.experimental.FieldNameConstants;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.mapper.PatchableMapWrapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
@ -37,7 +37,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@FieldNameConstants
|
||||
@DisplayName("Contact")
|
||||
public class HsOfficeContact implements Stringifyable, RbacObject<HsOfficeContact> {
|
||||
public class HsOfficeContact implements Stringifyable, BaseEntity<HsOfficeContact> {
|
||||
|
||||
private static Stringify<HsOfficeContact> toString = stringify(HsOfficeContact.class, "contact")
|
||||
.withProp(Fields.caption, HsOfficeContact::getCaption)
|
||||
|
@ -16,7 +16,6 @@ import jakarta.persistence.Table;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@FieldNameConstants
|
||||
@DisplayName("BareContact")
|
||||
public class HsOfficeContactBareEntity extends HsOfficeContact {
|
||||
|
||||
|
@ -22,11 +22,9 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@FieldNameConstants
|
||||
@DisplayName("RbacContact")
|
||||
public class HsOfficeContactRbacEntity extends HsOfficeContact {
|
||||
|
||||
|
||||
public static RbacView rbac() {
|
||||
return rbacViewFor("contact", HsOfficeContactRbacEntity.class)
|
||||
.withIdentityView(SQL.projection("caption"))
|
||||
|
@ -8,7 +8,7 @@ import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
@ -41,7 +41,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("CoopAssetsTransaction")
|
||||
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacObject<HsOfficeCoopAssetsTransactionEntity> {
|
||||
public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopAssetsTransactionEntity> {
|
||||
|
||||
private static Stringify<HsOfficeCoopAssetsTransactionEntity> stringify = stringify(HsOfficeCoopAssetsTransactionEntity.class)
|
||||
.withIdProp(HsOfficeCoopAssetsTransactionEntity::getTaggedMemberNumber)
|
||||
@ -107,7 +107,7 @@ public class HsOfficeCoopAssetsTransactionEntity implements Stringifyable, RbacO
|
||||
|
||||
@Override
|
||||
public HsOfficeCoopAssetsTransactionEntity load() {
|
||||
RbacObject.super.load();
|
||||
BaseEntity.super.load();
|
||||
membership.load();
|
||||
return this;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.membership.HsOfficeMembershipEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
@ -39,7 +39,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("CoopShareTransaction")
|
||||
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacObject<HsOfficeCoopSharesTransactionEntity> {
|
||||
public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, BaseEntity<HsOfficeCoopSharesTransactionEntity> {
|
||||
|
||||
private static Stringify<HsOfficeCoopSharesTransactionEntity> stringify = stringify(HsOfficeCoopSharesTransactionEntity.class)
|
||||
.withIdProp(HsOfficeCoopSharesTransactionEntity::getMemberNumberTagged)
|
||||
@ -104,7 +104,7 @@ public class HsOfficeCoopSharesTransactionEntity implements Stringifyable, RbacO
|
||||
|
||||
@Override
|
||||
public HsOfficeCoopSharesTransactionEntity load() {
|
||||
RbacObject.super.load();
|
||||
BaseEntity.super.load();
|
||||
membership.load();
|
||||
return this;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebito
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorPatchResource;
|
||||
import net.hostsharing.hsadminng.hs.office.generated.api.v1.model.HsOfficeDebitorResource;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
@ -82,7 +83,7 @@ public class HsOfficeDebitorController implements HsOfficeDebitorsApi {
|
||||
final var entityToSave = mapper.map(body, HsOfficeDebitorEntity.class);
|
||||
if ( body.getDebitorRel() != null ) {
|
||||
body.getDebitorRel().setType(DEBITOR.name());
|
||||
final var debitorRel = mapper.map(body.getDebitorRel(), HsOfficeRelation.class);
|
||||
final var debitorRel = mapper.map(body.getDebitorRel(), HsOfficeRelationBareEntity.class);
|
||||
entityToSave.setDebitorRel(relBareRepo.save(debitorRel));
|
||||
} else {
|
||||
final var debitorRelOptional = relBareRepo.findByUuid(body.getDebitorRelUuid());
|
||||
|
@ -10,7 +10,8 @@ import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
@ -59,7 +60,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("Debitor")
|
||||
public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>, Stringifyable {
|
||||
public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>, Stringifyable {
|
||||
|
||||
public static final String DEBITOR_NUMBER_TAG = "D-";
|
||||
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
||||
@ -129,7 +130,7 @@ public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>,
|
||||
|
||||
@Override
|
||||
public HsOfficeDebitorEntity load() {
|
||||
RbacObject.super.load();
|
||||
BaseEntity.super.load();
|
||||
if (partner != null) {
|
||||
partner.load();
|
||||
}
|
||||
@ -189,7 +190,7 @@ public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>,
|
||||
"defaultPrefix")
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelation.class, usingCase(DEBITOR),
|
||||
.importRootEntityAliasProxy("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
dependsOnColumn("debitorRelUuid"))
|
||||
.createPermission(DELETE).grantedTo("debitorRel", OWNER)
|
||||
@ -203,7 +204,7 @@ public class HsOfficeDebitorEntity implements RbacObject<HsOfficeDebitorEntity>,
|
||||
.toRole("refundBankAccount", ADMIN).grantRole("debitorRel", AGENT)
|
||||
.toRole("debitorRel", AGENT).grantRole("refundBankAccount", REFERRER)
|
||||
|
||||
.importEntityAlias("partnerRel", HsOfficeRelation.class, usingDefaultCase(),
|
||||
.importEntityAlias("partnerRel", HsOfficeRelationRbacEntity.class, usingDefaultCase(),
|
||||
dependsOnColumn("debitorRelUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
|
@ -8,8 +8,8 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.partner.HsOfficePartnerEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
@ -62,7 +62,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("Membership")
|
||||
public class HsOfficeMembershipEntity implements RbacObject<HsOfficeMembershipEntity>, Stringifyable {
|
||||
public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEntity>, Stringifyable {
|
||||
|
||||
public static final String MEMBER_NUMBER_TAG = "M-";
|
||||
public static final String TWO_DECIMAL_DIGITS = "^([0-9]{2})$";
|
||||
@ -102,7 +102,7 @@ public class HsOfficeMembershipEntity implements RbacObject<HsOfficeMembershipEn
|
||||
|
||||
@Override
|
||||
public HsOfficeMembershipEntity load() {
|
||||
RbacObject.super.load();
|
||||
BaseEntity.super.load();
|
||||
partner.load();
|
||||
return this;
|
||||
}
|
||||
@ -165,7 +165,7 @@ public class HsOfficeMembershipEntity implements RbacObject<HsOfficeMembershipEn
|
||||
.withRestrictedViewOrderBy(SQL.projection("validity"))
|
||||
.withUpdatableColumns("validity", "membershipFeeBillable", "status")
|
||||
|
||||
.importEntityAlias("partnerRel", HsOfficeRelation.class, usingDefaultCase(),
|
||||
.importEntityAlias("partnerRel", HsOfficeRelationRbacEntity.class, usingDefaultCase(),
|
||||
dependsOnColumn("partnerUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
|
@ -14,7 +14,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareRepository;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||
import net.hostsharing.hsadminng.mapper.Mapper;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@ -142,7 +142,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
return ResponseEntity.ok(mapped);
|
||||
}
|
||||
|
||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelation previousPartnerRel) {
|
||||
private void optionallyCreateExPartnerRelation(final HsOfficePartnerEntity saved, final HsOfficeRelationBareEntity previousPartnerRel) {
|
||||
if (!saved.getPartnerRel().getUuid().equals(previousPartnerRel.getUuid())) {
|
||||
relationRepo.save(previousPartnerRel.toBuilder().uuid(null).type(EX_PARTNER).build());
|
||||
}
|
||||
@ -166,7 +166,7 @@ public class HsOfficePartnerController implements HsOfficePartnersApi {
|
||||
return entity;
|
||||
}
|
||||
|
||||
private <E extends RbacObject> E ref(final Class<E> entityClass, final UUID uuid) {
|
||||
private <E extends BaseEntity> E ref(final Class<E> entityClass, final UUID uuid) {
|
||||
try {
|
||||
return em.getReference(entityClass, uuid);
|
||||
} catch (final Throwable exc) {
|
||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.hs.office.partner;
|
||||
|
||||
import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
@ -26,7 +26,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("PartnerDetails")
|
||||
public class HsOfficePartnerDetailsEntity implements RbacObject<HsOfficePartnerDetailsEntity>, Stringifyable {
|
||||
public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerDetailsEntity>, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficePartnerDetailsEntity> stringify = stringify(
|
||||
HsOfficePartnerDetailsEntity.class,
|
||||
|
@ -9,7 +9,8 @@ import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContact;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
@ -41,7 +42,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("Partner")
|
||||
public class HsOfficePartnerEntity implements Stringifyable, RbacObject<HsOfficePartnerEntity> {
|
||||
public class HsOfficePartnerEntity implements Stringifyable, BaseEntity<HsOfficePartnerEntity> {
|
||||
|
||||
public static final String PARTNER_NUMBER_TAG = "P-";
|
||||
|
||||
@ -78,7 +79,7 @@ public class HsOfficePartnerEntity implements Stringifyable, RbacObject<HsOffice
|
||||
|
||||
@Override
|
||||
public HsOfficePartnerEntity load() {
|
||||
RbacObject.super.load();
|
||||
BaseEntity.super.load();
|
||||
partnerRel.load();
|
||||
details.load();
|
||||
return this;
|
||||
@ -104,7 +105,7 @@ public class HsOfficePartnerEntity implements Stringifyable, RbacObject<HsOffice
|
||||
.withUpdatableColumns("partnerRelUuid")
|
||||
.toRole("global", ADMIN).grantPermission(INSERT)
|
||||
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelation.class,
|
||||
.importRootEntityAliasProxy("partnerRel", HsOfficeRelationRbacEntity.class,
|
||||
usingDefaultCase(),
|
||||
directlyFetchedByDependsOnColumn(),
|
||||
dependsOnColumn("partnerRelUuid"))
|
||||
|
@ -3,7 +3,7 @@ package net.hostsharing.hsadminng.hs.office.person;
|
||||
import lombok.*;
|
||||
import lombok.experimental.FieldNameConstants;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
@ -30,7 +30,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@AllArgsConstructor
|
||||
@FieldNameConstants
|
||||
@DisplayName("Person")
|
||||
public class HsOfficePersonEntity implements RbacObject<HsOfficePersonEntity>, Stringifyable {
|
||||
public class HsOfficePersonEntity implements BaseEntity<HsOfficePersonEntity>, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficePersonEntity> toString = stringify(HsOfficePersonEntity.class, "person")
|
||||
.withProp(Fields.personType, HsOfficePersonEntity::getPersonType)
|
||||
|
@ -5,7 +5,7 @@ import lombok.experimental.FieldNameConstants;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactBareEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.person.HsOfficePersonEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
|
||||
@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@Setter
|
||||
@SuperBuilder(toBuilder = true)
|
||||
@FieldNameConstants
|
||||
public class HsOfficeRelation implements RbacObject<HsOfficeRelation>, Stringifyable {
|
||||
public class HsOfficeRelation implements BaseEntity<HsOfficeRelation>, Stringifyable {
|
||||
|
||||
private static Stringify<HsOfficeRelation> toString = stringify(HsOfficeRelation.class, "rel")
|
||||
.withProp(Fields.anchor, HsOfficeRelation::getAnchor)
|
||||
@ -64,7 +64,7 @@ public class HsOfficeRelation implements RbacObject<HsOfficeRelation>, Stringify
|
||||
|
||||
@Override
|
||||
public HsOfficeRelation load() {
|
||||
RbacObject.super.load();
|
||||
BaseEntity.super.load();
|
||||
anchor.load();
|
||||
holder.load();
|
||||
contact.load();
|
||||
|
@ -17,19 +17,19 @@ public interface HsOfficeRelationBareRepository extends Repository<HsOfficeRelat
|
||||
}
|
||||
|
||||
@Query(value = """
|
||||
SELECT p.* FROM hs_office_relation_rv AS p
|
||||
SELECT p.* FROM hs_office_relation AS p
|
||||
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
|
||||
""", nativeQuery = true)
|
||||
List<HsOfficeRelationBareEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
|
||||
|
||||
@Query(value = """
|
||||
SELECT p.* FROM hs_office_relation_rv AS p
|
||||
SELECT p.* FROM hs_office_relation AS p
|
||||
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
|
||||
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
|
||||
""", nativeQuery = true)
|
||||
List<HsOfficeRelationBareEntity> findRelationRelatedToPersonUuidAndRelationTypeString(@NotNull UUID personUuid, String relationType);
|
||||
|
||||
HsOfficeRelationBareEntity save(final HsOfficeRelation entity);
|
||||
HsOfficeRelationBareEntity save(final HsOfficeRelationBareEntity entity);
|
||||
|
||||
long count();
|
||||
|
||||
|
@ -6,8 +6,8 @@ import lombok.*;
|
||||
import net.hostsharing.hsadminng.errors.DisplayName;
|
||||
import net.hostsharing.hsadminng.hs.office.bankaccount.HsOfficeBankAccountEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.debitor.HsOfficeDebitorEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationRbacEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.stringify.Stringify;
|
||||
import net.hostsharing.hsadminng.stringify.Stringifyable;
|
||||
@ -40,7 +40,7 @@ import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@DisplayName("SEPA-Mandate")
|
||||
public class HsOfficeSepaMandateEntity implements Stringifyable, RbacObject<HsOfficeSepaMandateEntity> {
|
||||
public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOfficeSepaMandateEntity> {
|
||||
|
||||
private static Stringify<HsOfficeSepaMandateEntity> stringify = stringify(HsOfficeSepaMandateEntity.class)
|
||||
.withProp(e -> e.getBankAccount().getIban())
|
||||
@ -110,7 +110,7 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, RbacObject<HsOf
|
||||
.withRestrictedViewOrderBy(expression("validity"))
|
||||
.withUpdatableColumns("reference", "agreement", "validity")
|
||||
|
||||
.importEntityAlias("debitorRel", HsOfficeRelation.class, usingCase(DEBITOR),
|
||||
.importEntityAlias("debitorRel", HsOfficeRelationRbacEntity.class, usingCase(DEBITOR),
|
||||
dependsOnColumn("debitorUuid"),
|
||||
fetchedBySql("""
|
||||
SELECT ${columns}
|
||||
|
@ -2,7 +2,7 @@ package net.hostsharing.hsadminng.rbac.rbacdef;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.scanners.TypeAnnotationsScanner;
|
||||
|
||||
@ -12,6 +12,7 @@ import jakarta.persistence.Version;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
@ -89,11 +90,11 @@ public class RbacView {
|
||||
* @param <E>
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public static <E extends RbacObject> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
|
||||
public static <E extends BaseEntity> RbacView rbacViewFor(final String alias, final Class<E> entityClass) {
|
||||
return new RbacView(alias, entityClass);
|
||||
}
|
||||
|
||||
RbacView(final String alias, final Class<? extends RbacObject> entityClass) {
|
||||
RbacView(final String alias, final Class<? extends BaseEntity> entityClass) {
|
||||
rootEntityAlias = new EntityAlias(alias, entityClass);
|
||||
entityAliases.put(alias, rootEntityAlias);
|
||||
new RbacUserReference(CREATOR);
|
||||
@ -253,7 +254,7 @@ public class RbacView {
|
||||
.orElseGet(() -> new RbacPermissionDefinition(entityAlias, permission, null, true));
|
||||
}
|
||||
|
||||
public <EC extends RbacObject> RbacView declarePlaceholderEntityAliases(final String... aliasNames) {
|
||||
public <EC extends BaseEntity> RbacView declarePlaceholderEntityAliases(final String... aliasNames) {
|
||||
for (String alias : aliasNames) {
|
||||
entityAliases.put(alias, new EntityAlias(alias));
|
||||
}
|
||||
@ -286,9 +287,9 @@ public class RbacView {
|
||||
* @param <EC>
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public <EC extends RbacObject> RbacView importRootEntityAliasProxy(
|
||||
public <EC extends BaseEntity> RbacView importRootEntityAliasProxy(
|
||||
final String aliasName,
|
||||
final Class<? extends RbacObject> entityClass,
|
||||
final Class<? extends BaseEntity> entityClass,
|
||||
final ColumnValue forCase,
|
||||
final SQL fetchSql,
|
||||
final Column dependsOnColum) {
|
||||
@ -312,7 +313,7 @@ public class RbacView {
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public RbacView importSubEntityAlias(
|
||||
final String aliasName, final Class<? extends RbacObject> entityClass,
|
||||
final String aliasName, final Class<? extends BaseEntity> entityClass,
|
||||
final SQL fetchSql, final Column dependsOnColum) {
|
||||
importEntityAliasImpl(aliasName, entityClass, usingDefaultCase(), fetchSql, dependsOnColum, true, NOT_NULL);
|
||||
return this;
|
||||
@ -349,14 +350,14 @@ public class RbacView {
|
||||
* a JPA entity class extending RbacObject
|
||||
*/
|
||||
public RbacView importEntityAlias(
|
||||
final String aliasName, final Class<? extends RbacObject> entityClass, final ColumnValue usingCase,
|
||||
final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
|
||||
final Column dependsOnColum, final SQL fetchSql, final Nullable nullable) {
|
||||
importEntityAliasImpl(aliasName, entityClass, usingCase, fetchSql, dependsOnColum, false, nullable);
|
||||
return this;
|
||||
}
|
||||
|
||||
private EntityAlias importEntityAliasImpl(
|
||||
final String aliasName, final Class<? extends RbacObject> entityClass, final ColumnValue usingCase,
|
||||
final String aliasName, final Class<? extends BaseEntity> entityClass, final ColumnValue usingCase,
|
||||
final SQL fetchSql, final Column dependsOnColum, boolean asSubEntity, final Nullable nullable) {
|
||||
|
||||
final var entityAlias = ofNullable(entityAliases.get(aliasName))
|
||||
@ -378,7 +379,7 @@ public class RbacView {
|
||||
return entityAlias;
|
||||
}
|
||||
|
||||
private static RbacView rbacDefinition(final Class<? extends RbacObject> entityClass)
|
||||
private static RbacView rbacDefinition(final Class<? extends BaseEntity> entityClass)
|
||||
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
||||
return (RbacView) entityClass.getMethod("rbac").invoke(null);
|
||||
}
|
||||
@ -432,12 +433,22 @@ public class RbacView {
|
||||
}
|
||||
|
||||
private void verifyVersionColumnExists() {
|
||||
if (stream(rootEntityAlias.entityClass.getDeclaredFields())
|
||||
.noneMatch(f -> f.getAnnotation(Version.class) != null)) {
|
||||
final var clazz = rootEntityAlias.entityClass;
|
||||
if (!hasVersionColumn(clazz)) {
|
||||
throw new IllegalArgumentException("@Version field required in updatable entity " + rootEntityAlias.entityClass);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasVersionColumn(final Class<?> clazz) {
|
||||
if (stream(clazz.getDeclaredFields()).anyMatch(f -> f.getAnnotation(Version.class) != null)) {
|
||||
return true;
|
||||
}
|
||||
if (clazz.getSuperclass() != null) {
|
||||
return hasVersionColumn(clazz.getSuperclass());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts declaring a grant to a given role.
|
||||
*
|
||||
@ -900,13 +911,13 @@ public class RbacView {
|
||||
return distinctGrantDef;
|
||||
}
|
||||
|
||||
record EntityAlias(String aliasName, Class<? extends RbacObject> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
|
||||
record EntityAlias(String aliasName, Class<? extends BaseEntity> entityClass, ColumnValue usingCase, SQL fetchSql, Column dependsOnColum, boolean isSubEntity, Nullable nullable) {
|
||||
|
||||
public EntityAlias(final String aliasName) {
|
||||
this(aliasName, null, null, null, null, false, null);
|
||||
}
|
||||
|
||||
public EntityAlias(final String aliasName, final Class<? extends RbacObject> entityClass) {
|
||||
public EntityAlias(final String aliasName, final Class<? extends BaseEntity> entityClass) {
|
||||
this(aliasName, entityClass, null, null, null, false, null);
|
||||
}
|
||||
|
||||
@ -936,6 +947,10 @@ public class RbacView {
|
||||
}
|
||||
|
||||
private String withoutEntitySuffix(final String simpleEntityName) {
|
||||
// TODO.impl: maybe introduce an annotation like @RbacObjectName("hsOfficeContact")?
|
||||
if ( simpleEntityName.endsWith("RbacEntity")) {
|
||||
return simpleEntityName.substring(0, simpleEntityName.length() - "RbacEntity".length());
|
||||
}
|
||||
return simpleEntityName.substring(0, simpleEntityName.length() - "Entity".length());
|
||||
}
|
||||
|
||||
@ -1210,7 +1225,7 @@ public class RbacView {
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateRbacView(final Class<? extends RbacObject> c) {
|
||||
private static void generateRbacView(final Class<? extends BaseEntity> c) {
|
||||
final Method mainMethod = stream(c.getMethods()).filter(
|
||||
m -> isStatic(m.getModifiers()) && m.getName().equals("main")
|
||||
)
|
||||
@ -1227,17 +1242,20 @@ public class RbacView {
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<Class<? extends RbacObject>> findRbacEntityClasses(String packageName) {
|
||||
public static Set<Class<? extends BaseEntity>> findRbacEntityClasses(String packageName) {
|
||||
final var reflections = new Reflections(packageName, TypeAnnotationsScanner.class);
|
||||
return reflections.getTypesAnnotatedWith(Entity.class).stream()
|
||||
.filter(c -> stream(c.getInterfaces()).anyMatch(i -> i==RbacObject.class))
|
||||
.map(RbacView::castToSubclassOfRbacObject)
|
||||
.filter(c -> stream(c.getInterfaces()).anyMatch(i -> i== BaseEntity.class))
|
||||
.filter(c -> stream(c.getDeclaredMethods())
|
||||
.anyMatch(m -> m.getName().equals("rbac") && Modifier.isStatic(m.getModifiers()))
|
||||
)
|
||||
.map(RbacView::castToSubclassOfBaseEntity)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Class<? extends RbacObject> castToSubclassOfRbacObject(final Class<?> clazz) {
|
||||
return (Class<? extends RbacObject>) clazz;
|
||||
private static Class<? extends BaseEntity> castToSubclassOfBaseEntity(final Class<?> clazz) {
|
||||
return (Class<? extends BaseEntity>) clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,8 @@ import org.hibernate.Hibernate;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface RbacObject<T extends RbacObject<?>> {
|
||||
// TODO.impl: this class does not really belong into this package, but there is no right place yet
|
||||
public interface BaseEntity<T extends BaseEntity<?>> {
|
||||
UUID getUuid();
|
||||
|
||||
int getVersion();
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
|
||||
@ -24,7 +24,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TestCustomerEntity implements RbacObject<TestCustomerEntity> {
|
||||
public class TestCustomerEntity implements BaseEntity<TestCustomerEntity> {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.test.pac.TestPackageEntity;
|
||||
@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TestDomainEntity implements RbacObject<TestDomainEntity> {
|
||||
public class TestDomainEntity implements BaseEntity<TestDomainEntity> {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
|
@ -4,7 +4,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView;
|
||||
import net.hostsharing.hsadminng.rbac.rbacdef.RbacView.SQL;
|
||||
import net.hostsharing.hsadminng.rbac.test.cust.TestCustomerEntity;
|
||||
@ -27,7 +27,7 @@ import static net.hostsharing.hsadminng.rbac.rbacdef.RbacView.rbacViewFor;
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class TestPackageEntity implements RbacObject<TestPackageEntity> {
|
||||
public class TestPackageEntity implements BaseEntity<TestPackageEntity> {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
|
@ -197,8 +197,7 @@ begin
|
||||
from granted
|
||||
join RbacPermission perm on granted.descendantUuid = perm.uuid
|
||||
join RbacObject obj on obj.uuid = perm.objectUuid
|
||||
where perm.op = 'SELECT'
|
||||
and obj.objectTable = '%1$s'
|
||||
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
|
||||
limit 8001
|
||||
)
|
||||
select target.*
|
||||
|
@ -142,8 +142,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into test_customer not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into test_customer values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger test_customer_insert_permission_check_tg
|
||||
|
@ -207,8 +207,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into test_package not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into test_package values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger test_package_insert_permission_check_tg
|
||||
|
@ -206,8 +206,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into test_domain not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into test_domain values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger test_domain_insert_permission_check_tg
|
||||
|
@ -219,8 +219,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into hs_office_partner not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into hs_office_partner values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_partner_insert_permission_check_tg
|
||||
|
@ -123,8 +123,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into hs_office_partner_details not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into hs_office_partner_details values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_partner_details_insert_permission_check_tg
|
||||
|
@ -192,8 +192,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into hs_office_debitor not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into hs_office_debitor values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_debitor_insert_permission_check_tg
|
||||
|
@ -173,8 +173,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into hs_office_sepamandate not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into hs_office_sepamandate values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_sepamandate_insert_permission_check_tg
|
||||
|
@ -154,8 +154,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into hs_office_membership not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into hs_office_membership values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_membership_insert_permission_check_tg
|
||||
|
@ -130,8 +130,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into hs_office_coopsharestransaction not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into hs_office_coopsharestransaction values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_coopsharestransaction_insert_permission_check_tg
|
||||
|
@ -130,8 +130,8 @@ begin
|
||||
return NEW;
|
||||
end if;
|
||||
|
||||
raise exception '[403] insert into hs_office_coopassetstransaction not allowed for current subjects % (%)',
|
||||
currentSubjects(), currentSubjectsUuids();
|
||||
raise exception '[403] insert into hs_office_coopassetstransaction values(%) not allowed for current subjects % (%)',
|
||||
NEW, currentSubjects(), currentSubjectsUuids();
|
||||
end; $$;
|
||||
|
||||
create trigger hs_office_coopassetstransaction_insert_permission_check_tg
|
||||
|
@ -12,7 +12,7 @@ import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemEntity;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAssetEntity;
|
||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@ -346,7 +346,7 @@ public class ArchitectureTest {
|
||||
static final ArchRule tableNamesOfRbacEntitiesShouldEndWith_rv =
|
||||
classes()
|
||||
.that().areAnnotatedWith(Table.class)
|
||||
.and().areAssignableTo(RbacObject.class)
|
||||
.and().areAssignableTo(BaseEntity.class)
|
||||
.should(haveTableNameEndingWith_rv())
|
||||
.because("it's required that the table names of RBAC entities end with '_rv'");
|
||||
|
||||
|
@ -6,7 +6,7 @@ import com.opencsv.CSVReaderBuilder;
|
||||
import lombok.SneakyThrows;
|
||||
import net.hostsharing.hsadminng.hs.hosting.asset.HsHostingAsset;
|
||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.junit.jupiter.api.extension.BeforeEachCallback;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
@ -141,7 +141,7 @@ public class CsvDataImport extends ContextBasedTest {
|
||||
return record;
|
||||
}
|
||||
|
||||
public <T extends RbacObject> T persist(final Integer id, final T entity) {
|
||||
public <T extends BaseEntity> T persist(final Integer id, final T entity) {
|
||||
try {
|
||||
if (entity instanceof HsHostingAsset ha) {
|
||||
//noinspection unchecked
|
||||
@ -155,7 +155,7 @@ public class CsvDataImport extends ContextBasedTest {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public <T extends RbacObject> T persistViaEM(final Integer id, final T entity) {
|
||||
public <T extends BaseEntity> T persistViaEM(final Integer id, final T entity) {
|
||||
//System.out.println("persisting #" + entity.hashCode() + ": " + entity);
|
||||
em.persist(entity);
|
||||
// uncomment for debugging purposes
|
||||
@ -165,7 +165,7 @@ public class CsvDataImport extends ContextBasedTest {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public RbacObject<HsHostingAsset> persistViaSql(final Integer id, final HsHostingAsset entity) {
|
||||
public BaseEntity<HsHostingAsset> persistViaSql(final Integer id, final HsHostingAsset entity) {
|
||||
if (entity.getUuid() == null) {
|
||||
entity.setUuid(UUID.randomUUID());
|
||||
}
|
||||
@ -196,10 +196,10 @@ public class CsvDataImport extends ContextBasedTest {
|
||||
""")
|
||||
.setParameter("uuid", entity.getUuid())
|
||||
.setParameter("type", entity.getType().name())
|
||||
.setParameter("bookingitemuuid", ofNullable(entity.getBookingItem()).map(RbacObject::getUuid).orElse(null))
|
||||
.setParameter("parentassetuuid", ofNullable(entity.getParentAsset()).map(RbacObject::getUuid).orElse(null))
|
||||
.setParameter("assignedtoassetuuid", ofNullable(entity.getAssignedToAsset()).map(RbacObject::getUuid).orElse(null))
|
||||
.setParameter("alarmcontactuuid", ofNullable(entity.getAlarmContact()).map(RbacObject::getUuid).orElse(null))
|
||||
.setParameter("bookingitemuuid", ofNullable(entity.getBookingItem()).map(BaseEntity::getUuid).orElse(null))
|
||||
.setParameter("parentassetuuid", ofNullable(entity.getParentAsset()).map(BaseEntity::getUuid).orElse(null))
|
||||
.setParameter("assignedtoassetuuid", ofNullable(entity.getAssignedToAsset()).map(BaseEntity::getUuid).orElse(null))
|
||||
.setParameter("alarmcontactuuid", ofNullable(entity.getAlarmContact()).map(BaseEntity::getUuid).orElse(null))
|
||||
.setParameter("identifier", entity.getIdentifier())
|
||||
.setParameter("caption", entity.getCaption())
|
||||
.setParameter("config", entity.getConfig().toString())
|
||||
|
@ -18,7 +18,7 @@ import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelation;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationBareEntity;
|
||||
import net.hostsharing.hsadminng.hs.office.relation.HsOfficeRelationType;
|
||||
import net.hostsharing.hsadminng.hs.office.sepamandate.HsOfficeSepaMandateEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.test.JpaAttempt;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -698,7 +698,7 @@ public class ImportOfficeData extends CsvDataImport {
|
||||
assumeThat(partners.size()).isLessThanOrEqualTo(MAX_NUMBER_OF_TEST_DATA_PARTNERS);
|
||||
}
|
||||
|
||||
private <E extends RbacObject> void updateLegacyIds(
|
||||
private <E extends BaseEntity> void updateLegacyIds(
|
||||
Map<Integer, E> entities,
|
||||
final String legacyIdTable,
|
||||
final String legacyIdColumn) {
|
||||
|
@ -65,7 +65,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
HsOfficePersonRepository personRepo;
|
||||
|
||||
@Autowired
|
||||
HsOfficeRelationBareRepository relRepo;
|
||||
HsOfficeRelationBareRepository relBareRepo;
|
||||
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
@ -275,7 +275,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
|
||||
final var givenDebitorRelUUid = jpaAttempt.transacted(() -> {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
return relRepo.save(HsOfficeRelationRbacEntity.builder()
|
||||
return relBareRepo.save(HsOfficeRelationBareEntity.builder()
|
||||
.type(DEBITOR)
|
||||
.anchor(givenPartner.getPartnerRel().getHolder())
|
||||
.holder(givenBillingPerson)
|
||||
@ -435,7 +435,7 @@ class HsOfficeDebitorControllerAcceptanceTest extends ContextBasedTestWithCleanu
|
||||
.post("http://localhost/api/hs/office/debitors")
|
||||
.then().log().all().assertThat()
|
||||
.statusCode(400)
|
||||
.body("message", is("Unable to find HsOfficeRelationEntity with uuid 00000000-0000-0000-0000-000000000000"));
|
||||
.body("message", is("Unable to find HsOfficeRelationBareEntity with uuid 00000000-0000-0000-0000-000000000000"));
|
||||
// @formatter:on
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ class HsOfficePartnerControllerRestTest {
|
||||
.andExpect(status().is4xxClientError())
|
||||
.andExpect(jsonPath("statusCode", is(400)))
|
||||
.andExpect(jsonPath("statusPhrase", is("Bad Request")))
|
||||
.andExpect(jsonPath("message", startsWith("Cannot resolve HsOfficeContactEntity with uuid ")));
|
||||
.andExpect(jsonPath("message", startsWith("Cannot resolve HsOfficeContactBareEntity with uuid ")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,8 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTestWithClean
|
||||
|
||||
// then
|
||||
result.assertExceptionWithRootCauseMessage(JpaSystemException.class,
|
||||
"[403] insert into hs_office_partner_details not allowed for current subjects {hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}");
|
||||
"ERROR: [403] insert into hs_office_partner_details ",
|
||||
" not allowed for current subjects {hs_office_relation#HostsharingeG-with-PARTNER-ErbenBesslerMelBessler:TENANT}");
|
||||
}
|
||||
|
||||
private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.hostsharing.hsadminng.rbac.test;
|
||||
|
||||
import net.hostsharing.hsadminng.rbac.context.ContextBasedTest;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantEntity;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantRepository;
|
||||
import net.hostsharing.hsadminng.rbac.rbacgrant.RbacGrantsDiagramService;
|
||||
@ -50,7 +50,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
|
||||
@Autowired
|
||||
JpaAttempt jpaAttempt;
|
||||
|
||||
private TreeMap<UUID, Class<? extends RbacObject>> entitiesToCleanup = new TreeMap<>();
|
||||
private TreeMap<UUID, Class<? extends BaseEntity>> entitiesToCleanup = new TreeMap<>();
|
||||
|
||||
private static Long latestIntialTestDataSerialId;
|
||||
private static boolean countersInitialized = false;
|
||||
@ -64,19 +64,19 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
|
||||
|
||||
private TestInfo testInfo;
|
||||
|
||||
public <T extends RbacObject> T refresh(final T entity) {
|
||||
public <T extends BaseEntity> T refresh(final T entity) {
|
||||
final var merged = em.merge(entity);
|
||||
em.refresh(merged);
|
||||
return merged;
|
||||
}
|
||||
|
||||
public UUID toCleanup(final Class<? extends RbacObject> entityClass, final UUID uuidToCleanup) {
|
||||
public UUID toCleanup(final Class<? extends BaseEntity> entityClass, final UUID uuidToCleanup) {
|
||||
out.println("toCleanup(" + entityClass.getSimpleName() + ", " + uuidToCleanup + ")");
|
||||
entitiesToCleanup.put(uuidToCleanup, entityClass);
|
||||
return uuidToCleanup;
|
||||
}
|
||||
|
||||
public <E extends RbacObject> E toCleanup(final E entity) {
|
||||
public <E extends BaseEntity> E toCleanup(final E entity) {
|
||||
out.println("toCleanup(" + entity.getClass() + ", " + entity.getUuid());
|
||||
if ( entity.getUuid() == null ) {
|
||||
throw new IllegalArgumentException("only persisted entities with valid uuid allowed");
|
||||
@ -85,7 +85,7 @@ public abstract class ContextBasedTestWithCleanup extends ContextBasedTest {
|
||||
return entity;
|
||||
}
|
||||
|
||||
protected void cleanupAllNew(final Class<? extends RbacObject> entityClass) {
|
||||
protected void cleanupAllNew(final Class<? extends BaseEntity> entityClass) {
|
||||
if (initialRbacObjects == null) {
|
||||
out.println("skipping cleanupAllNew: " + entityClass.getSimpleName());
|
||||
return; // TODO: seems @AfterEach is called without any @BeforeEach
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.hostsharing.hsadminng.rbac.test;
|
||||
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class EntityList {
|
||||
|
||||
public static <E extends RbacObject> E one(final List<E> entities) {
|
||||
public static <E extends BaseEntity> E one(final List<E> entities) {
|
||||
assertThat(entities).hasSize(1);
|
||||
return entities.stream().findFirst().orElseThrow();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package net.hostsharing.hsadminng.rbac.test;
|
||||
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.RbacObject;
|
||||
import net.hostsharing.hsadminng.rbac.rbacobject.BaseEntity;
|
||||
import net.hostsharing.hsadminng.mapper.EntityPatcher;
|
||||
import org.junit.jupiter.api.Named;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -233,7 +233,7 @@ public abstract class PatchUnitTestBase<R, E> {
|
||||
}
|
||||
}
|
||||
|
||||
protected static class JsonNullableProperty<R, RV, E extends RbacObject, EV> extends Property<R, RV, E, EV> {
|
||||
protected static class JsonNullableProperty<R, RV, E extends BaseEntity, EV> extends Property<R, RV, E, EV> {
|
||||
|
||||
private final BiConsumer<R, JsonNullable<RV>> resourceSetter;
|
||||
public final RV givenPatchValue;
|
||||
|
Loading…
Reference in New Issue
Block a user