refactor lock entity
This commit is contained in:
parent
0c34502f08
commit
880e8c5aa8
|
@ -97,5 +97,11 @@ public class AuditableAction {
|
||||||
public static final EventId Dashboard_MyDashboardStatistics = new EventId(15001, "Dashboard_MyDashboardStatistics");
|
public static final EventId Dashboard_MyDashboardStatistics = new EventId(15001, "Dashboard_MyDashboardStatistics");
|
||||||
public static final EventId Dashboard_PublicDashboardStatistics = new EventId(15002, "Dashboard_PublicDashboardStatistics");
|
public static final EventId Dashboard_PublicDashboardStatistics = new EventId(15002, "Dashboard_PublicDashboardStatistics");
|
||||||
|
|
||||||
|
public static final EventId Notification_Persist = new EventId(16000, "Notification_Persist");
|
||||||
|
|
||||||
|
public static final EventId Lock_Query = new EventId(17000, "Lock_Query");
|
||||||
|
public static final EventId Lock_Lookup = new EventId(17001, "Lock_Lookup");
|
||||||
|
public static final EventId Lock_Persist = new EventId(17002, "Lock_Persist");
|
||||||
|
public static final EventId Lock_Delete = new EventId(17003, "Lock_Delete");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,5 +161,10 @@ public final class Permission {
|
||||||
public static String EditTenantUser = "EditTenantUser";
|
public static String EditTenantUser = "EditTenantUser";
|
||||||
public static String DeleteTenantUser = "DeleteTenantUser";
|
public static String DeleteTenantUser = "DeleteTenantUser";
|
||||||
|
|
||||||
|
//Lock
|
||||||
|
public static String BrowseLock = "BrowseLock";
|
||||||
|
public static String EditLock = "EditLock";
|
||||||
|
public static String DeleteLock = "DeleteLock";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package eu.eudat.commons.enums;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
|
import eu.eudat.data.converters.enums.DatabaseEnum;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum LockTargetType implements DatabaseEnum<Short> {
|
||||||
|
Dmp((short) 0),
|
||||||
|
Decription((short) 1);
|
||||||
|
private final Short value;
|
||||||
|
|
||||||
|
LockTargetType(Short value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
public Short getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<Short, LockTargetType> map = EnumUtils.getEnumValueMap(LockTargetType.class);
|
||||||
|
|
||||||
|
public static LockTargetType of(Short i) {
|
||||||
|
return map.get(i);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package eu.eudat.data;
|
||||||
|
|
||||||
|
import eu.eudat.commons.enums.LockTargetType;
|
||||||
|
import eu.eudat.data.converters.enums.LockTargetTypeConverter;
|
||||||
|
import eu.eudat.data.tenant.TenantScopedBaseEntity;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "\"Lock\"")
|
||||||
|
public class LockEntity extends TenantScopedBaseEntity {
|
||||||
|
@Id
|
||||||
|
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
|
||||||
|
private UUID id;
|
||||||
|
public static final String _id = "id";
|
||||||
|
|
||||||
|
@Column(name = "target", columnDefinition = "uuid", updatable = false, nullable = false)
|
||||||
|
private UUID target;
|
||||||
|
public static final String _target = "target";
|
||||||
|
|
||||||
|
@Column(name = "target_type", nullable = false)
|
||||||
|
@Convert(converter = LockTargetTypeConverter.class)
|
||||||
|
private LockTargetType targetType;
|
||||||
|
public static final String _targetType = "targetType";
|
||||||
|
|
||||||
|
|
||||||
|
@Column(name = "locked_by", columnDefinition = "uuid", updatable = false, nullable = false)
|
||||||
|
private UUID lockedBy;
|
||||||
|
public static final String _lockedBy = "lockedBy";
|
||||||
|
|
||||||
|
|
||||||
|
@Column(name = "locked_at", nullable = false)
|
||||||
|
private Instant lockedAt = null;
|
||||||
|
public static final String _lockedAt = "lockedAt";
|
||||||
|
|
||||||
|
@Column(name = "touched_at", nullable = true)
|
||||||
|
private Instant touchedAt;
|
||||||
|
public static final String _touchedAt = "touchedAt";
|
||||||
|
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(UUID target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTargetType getTargetType() {
|
||||||
|
return targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetType(LockTargetType targetType) {
|
||||||
|
this.targetType = targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getLockedBy() {
|
||||||
|
return lockedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockedBy(UUID lockedBy) {
|
||||||
|
this.lockedBy = lockedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getLockedAt() {
|
||||||
|
return lockedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockedAt(Instant lockedAt) {
|
||||||
|
this.lockedAt = lockedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getTouchedAt() {
|
||||||
|
return touchedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTouchedAt(Instant touchedAt) {
|
||||||
|
this.touchedAt = touchedAt;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package eu.eudat.data.converters.enums;
|
||||||
|
|
||||||
|
import eu.eudat.commons.enums.LockTargetType;
|
||||||
|
import jakarta.persistence.Converter;
|
||||||
|
|
||||||
|
@Converter
|
||||||
|
public class LockTargetTypeConverter extends DatabaseEnumConverter<LockTargetType, Short>{
|
||||||
|
protected LockTargetType of(Short i) {
|
||||||
|
return LockTargetType.of(i);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package eu.eudat.model;
|
||||||
|
|
||||||
|
import eu.eudat.commons.enums.LockTargetType;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Lock {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
public static final String _id = "id";
|
||||||
|
|
||||||
|
private UUID target;
|
||||||
|
public static final String _target = "target";
|
||||||
|
|
||||||
|
private LockTargetType targetType;
|
||||||
|
public static final String _targetType = "targetType";
|
||||||
|
|
||||||
|
private User lockedBy;
|
||||||
|
public static final String _lockedBy = "lockedBy";
|
||||||
|
|
||||||
|
private Instant lockedAt;
|
||||||
|
public static final String _lockedAt = "lockedAt";
|
||||||
|
|
||||||
|
private Instant touchedAt;
|
||||||
|
public static final String _touchedAt = "touchedAt";
|
||||||
|
|
||||||
|
private Tenant tenant;
|
||||||
|
public static final String _tenant = "tenant";
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
|
||||||
|
public static final String _hash = "hash";
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(UUID target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTargetType getTargetType() {
|
||||||
|
return targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetType(LockTargetType targetType) {
|
||||||
|
this.targetType = targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getLockedBy() {
|
||||||
|
return lockedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockedBy(User lockedBy) {
|
||||||
|
this.lockedBy = lockedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getLockedAt() {
|
||||||
|
return lockedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockedAt(Instant lockedAt) {
|
||||||
|
this.lockedAt = lockedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Instant getTouchedAt() {
|
||||||
|
return touchedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTouchedAt(Instant touchedAt) {
|
||||||
|
this.touchedAt = touchedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tenant getTenant() {
|
||||||
|
return tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenant(Tenant tenant) {
|
||||||
|
this.tenant = tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(String hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
package eu.eudat.model.builder;
|
||||||
|
|
||||||
|
import eu.eudat.authorization.AuthorizationFlags;
|
||||||
|
import eu.eudat.commons.XmlHandlingService;
|
||||||
|
import eu.eudat.convention.ConventionService;
|
||||||
|
import eu.eudat.data.LockEntity;
|
||||||
|
import eu.eudat.model.Lock;
|
||||||
|
import eu.eudat.model.Tenant;
|
||||||
|
import eu.eudat.model.User;
|
||||||
|
import eu.eudat.query.TenantQuery;
|
||||||
|
import eu.eudat.query.UserQuery;
|
||||||
|
import gr.cite.tools.data.builder.BuilderFactory;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.DataLogEntry;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class LockBuilder extends BaseBuilder<Lock, LockEntity>{
|
||||||
|
|
||||||
|
private final BuilderFactory builderFactory;
|
||||||
|
private final QueryFactory queryFactory;
|
||||||
|
private final XmlHandlingService xmlHandlingService;
|
||||||
|
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LockBuilder(
|
||||||
|
ConventionService conventionService,
|
||||||
|
BuilderFactory builderFactory, QueryFactory queryFactory, XmlHandlingService xmlHandlingService) {
|
||||||
|
super(conventionService, new LoggerService(LoggerFactory.getLogger(LockBuilder.class)));
|
||||||
|
this.builderFactory = builderFactory;
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.xmlHandlingService = xmlHandlingService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockBuilder authorize(EnumSet<AuthorizationFlags> values) {
|
||||||
|
this.authorize = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Lock> build(FieldSet fields, List<LockEntity> data) throws MyApplicationException {
|
||||||
|
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
|
||||||
|
this.logger.trace(new DataLogEntry("requested fields", fields));
|
||||||
|
if (fields == null || data == null || fields.isEmpty())
|
||||||
|
return new ArrayList<>();
|
||||||
|
|
||||||
|
FieldSet userFields = fields.extractPrefixed(this.asPrefix(Lock._lockedBy));
|
||||||
|
Map<UUID, User> userMap = this.collectUsers(userFields, data);
|
||||||
|
|
||||||
|
FieldSet tenantFields = fields.extractPrefixed(this.asPrefix(Lock._tenant));
|
||||||
|
Map<UUID, Tenant> tenantMap = this.collectTenants(tenantFields, data);
|
||||||
|
|
||||||
|
List<Lock> models = new ArrayList<>();
|
||||||
|
for (LockEntity d : data) {
|
||||||
|
Lock m = new Lock();
|
||||||
|
if (fields.hasField(this.asIndexer(Lock._id))) m.setId(d.getId());
|
||||||
|
if (fields.hasField(this.asIndexer(Lock._target))) m.setTarget(d.getTarget());
|
||||||
|
if (fields.hasField(this.asIndexer(Lock._targetType))) m.setTargetType(d.getTargetType());
|
||||||
|
if (fields.hasField(this.asIndexer(Lock._lockedAt))) m.setLockedAt(d.getLockedAt());
|
||||||
|
if (fields.hasField(this.asIndexer(Lock._touchedAt))) m.setTouchedAt(d.getTouchedAt());
|
||||||
|
if (fields.hasField(this.asIndexer(Lock._hash))) m.setHash(this.hashValue(d.getTouchedAt()));
|
||||||
|
if (!userFields.isEmpty() && userMap != null && userMap.containsKey(d.getLockedBy())) m.setLockedBy(userMap.get(d.getLockedBy()));
|
||||||
|
if (!tenantFields.isEmpty() && tenantMap != null && tenantMap.containsKey(d.getTenantId())) m.setTenant(tenantMap.get(d.getTenantId()));
|
||||||
|
models.add(m);
|
||||||
|
}
|
||||||
|
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
|
||||||
|
return models;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<UUID, User> collectUsers(FieldSet fields, List<LockEntity> data) throws MyApplicationException {
|
||||||
|
if (fields.isEmpty() || data.isEmpty())
|
||||||
|
return null;
|
||||||
|
this.logger.debug("checking related - {}", User.class.getSimpleName());
|
||||||
|
|
||||||
|
Map<UUID, User> itemMap;
|
||||||
|
if (!fields.hasOtherField(this.asIndexer(User._id))) {
|
||||||
|
itemMap = this.asEmpty(
|
||||||
|
data.stream().map(LockEntity::getLockedBy).distinct().collect(Collectors.toList()),
|
||||||
|
x -> {
|
||||||
|
User item = new User();
|
||||||
|
item.setId(x);
|
||||||
|
return item;
|
||||||
|
},
|
||||||
|
User::getId);
|
||||||
|
} else {
|
||||||
|
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(User._id);
|
||||||
|
UserQuery q = this.queryFactory.query(UserQuery.class).authorize(this.authorize).ids(data.stream().map(LockEntity::getLockedBy).distinct().collect(Collectors.toList()));
|
||||||
|
itemMap = this.builderFactory.builder(UserBuilder.class).authorize(this.authorize).asForeignKey(q, clone, User::getId);
|
||||||
|
}
|
||||||
|
if (!fields.hasField(User._id)) {
|
||||||
|
itemMap.forEach((id, item) -> {
|
||||||
|
if (item != null)
|
||||||
|
item.setId(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<UUID, Tenant> collectTenants(FieldSet fields, List<LockEntity> datas) throws MyApplicationException {
|
||||||
|
if (fields.isEmpty() || datas.isEmpty()) return null;
|
||||||
|
this.logger.debug("checking related - {}", Tenant.class.getSimpleName());
|
||||||
|
|
||||||
|
Map<UUID, Tenant> itemMap = null;
|
||||||
|
if (!fields.hasOtherField(this.asIndexer(Tenant._id))) {
|
||||||
|
itemMap = this.asEmpty(
|
||||||
|
datas.stream().map(x -> x.getTenantId()).distinct().collect(Collectors.toList()),
|
||||||
|
x -> {
|
||||||
|
Tenant item = new Tenant();
|
||||||
|
item.setId(x);
|
||||||
|
return item;
|
||||||
|
},
|
||||||
|
x -> x.getId());
|
||||||
|
} else {
|
||||||
|
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(Tenant._id);
|
||||||
|
TenantQuery q = this.queryFactory.query(TenantQuery.class).authorize(this.authorize).ids(datas.stream().map(x -> x.getTenantId()).distinct().collect(Collectors.toList()));
|
||||||
|
itemMap = this.builderFactory.builder(TenantBuilder.class).authorize(this.authorize).asForeignKey(q, clone, x -> x.getId());
|
||||||
|
}
|
||||||
|
if (!fields.hasField(Tenant._id)) {
|
||||||
|
itemMap.values().stream().filter(x -> x != null).map(x -> {
|
||||||
|
x.setId(null);
|
||||||
|
return x;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package eu.eudat.model.censorship;
|
||||||
|
|
||||||
|
import eu.eudat.authorization.OwnedResource;
|
||||||
|
import eu.eudat.authorization.Permission;
|
||||||
|
import eu.eudat.convention.ConventionService;
|
||||||
|
import eu.eudat.model.Lock;
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
|
import gr.cite.tools.data.censor.CensorFactory;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.DataLogEntry;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class LockCensor extends BaseCensor {
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(LockCensor.class));
|
||||||
|
|
||||||
|
protected final AuthorizationService authService;
|
||||||
|
protected final CensorFactory censorFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LockCensor(
|
||||||
|
ConventionService conventionService,
|
||||||
|
AuthorizationService authService,
|
||||||
|
CensorFactory censorFactory
|
||||||
|
) {
|
||||||
|
super(conventionService);
|
||||||
|
this.authService = authService;
|
||||||
|
this.censorFactory = censorFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void censor(FieldSet fields, UUID userId) throws MyForbiddenException {
|
||||||
|
logger.debug(new DataLogEntry("censoring fields", fields));
|
||||||
|
if (this.isEmpty(fields)) return;
|
||||||
|
this.authService.authorizeAtLeastOneForce(userId != null ? List.of(new OwnedResource(userId)) : null, Permission.BrowseLock);
|
||||||
|
FieldSet tenantFields = fields.extractPrefixed(this.asIndexerPrefix(Lock._tenant));
|
||||||
|
this.censorFactory.censor(TenantCensor.class).censor(tenantFields, null);
|
||||||
|
FieldSet userFields = fields.extractPrefixed(this.asIndexerPrefix(Lock._lockedBy));
|
||||||
|
this.censorFactory.censor(UserCensor.class).censor(userFields, userId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package eu.eudat.model.deleter;
|
||||||
|
|
||||||
|
import eu.eudat.data.LockEntity;
|
||||||
|
import eu.eudat.query.LockQuery;
|
||||||
|
import gr.cite.tools.data.deleter.Deleter;
|
||||||
|
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import gr.cite.tools.logging.MapLogEntry;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class LockDeleter implements Deleter {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(LockDeleter.class));
|
||||||
|
private final EntityManager entityManager;
|
||||||
|
|
||||||
|
protected final QueryFactory queryFactory;
|
||||||
|
|
||||||
|
protected final DeleterFactory deleterFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LockDeleter(
|
||||||
|
EntityManager entityManager,
|
||||||
|
QueryFactory queryFactory,
|
||||||
|
DeleterFactory deleterFactory
|
||||||
|
) {
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.deleterFactory = deleterFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAndSaveByIds(List<UUID> ids) throws InvalidApplicationException {
|
||||||
|
logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids));
|
||||||
|
List<LockEntity> data = this.queryFactory.query(LockQuery.class).ids(ids).collect();
|
||||||
|
logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0));
|
||||||
|
this.deleteAndSave(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAndSave(List<LockEntity> data) throws InvalidApplicationException {
|
||||||
|
logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0));
|
||||||
|
this.delete(data);
|
||||||
|
logger.trace("saving changes");
|
||||||
|
this.entityManager.flush();
|
||||||
|
logger.trace("changes saved");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(List<LockEntity> data) throws InvalidApplicationException {
|
||||||
|
logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0));
|
||||||
|
if (data == null || data.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (LockEntity item : data) {
|
||||||
|
logger.trace("deleting item {}", item.getId());
|
||||||
|
this.entityManager.remove(item);
|
||||||
|
logger.trace("removed item");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -82,6 +82,12 @@ public class UserDeleter implements Deleter {
|
||||||
UserContactInfoDeleter deleter = this.deleterFactory.deleter(UserContactInfoDeleter.class);
|
UserContactInfoDeleter deleter = this.deleterFactory.deleter(UserContactInfoDeleter.class);
|
||||||
deleter.delete(items);
|
deleter.delete(items);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
logger.debug("checking related - {}", TenantUserEntity.class.getSimpleName());
|
||||||
|
List<TenantUserEntity> items = this.queryFactory.query(TenantUserQuery.class).userIds(ids).collect();
|
||||||
|
TenantUserDeleter deleter = this.deleterFactory.deleter(TenantUserDeleter.class);
|
||||||
|
deleter.delete(items);
|
||||||
|
}
|
||||||
// {
|
// {
|
||||||
// logger.debug("checking related - {}", DmpUserEntity.class.getSimpleName());
|
// logger.debug("checking related - {}", DmpUserEntity.class.getSimpleName());
|
||||||
// List<DmpUserEntity> items = this.queryFactory.query(DmpUserQuery.class).userIds(ids).collect();
|
// List<DmpUserEntity> items = this.queryFactory.query(DmpUserQuery.class).userIds(ids).collect();
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package eu.eudat.model.persist;
|
||||||
|
|
||||||
|
import eu.eudat.commons.enums.LockTargetType;
|
||||||
|
import eu.eudat.commons.validation.FieldNotNullIfOtherSet;
|
||||||
|
import eu.eudat.commons.validation.ValidEnum;
|
||||||
|
import eu.eudat.commons.validation.ValidId;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@FieldNotNullIfOtherSet(message = "{validation.hashempty}")
|
||||||
|
public class LockPersist {
|
||||||
|
|
||||||
|
@ValidId(message = "{validation.invalidid}")
|
||||||
|
private UUID id;
|
||||||
|
|
||||||
|
@Valid
|
||||||
|
private UUID target;
|
||||||
|
|
||||||
|
@ValidEnum(message = "{validation.empty}")
|
||||||
|
private LockTargetType targetType;
|
||||||
|
|
||||||
|
@Valid
|
||||||
|
private UUID lockedBy;
|
||||||
|
|
||||||
|
public static final String _touchedAt = "touchedAt";
|
||||||
|
|
||||||
|
private String hash;
|
||||||
|
|
||||||
|
public static final String _hash = "hash";
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(UUID id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getTarget() {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTarget(UUID target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockTargetType getTargetType() {
|
||||||
|
return targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetType(LockTargetType targetType) {
|
||||||
|
this.targetType = targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getLockedBy() {
|
||||||
|
return lockedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLockedBy(UUID lockedBy) {
|
||||||
|
this.lockedBy = lockedBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(String hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,173 @@
|
||||||
|
package eu.eudat.query;
|
||||||
|
|
||||||
|
import eu.eudat.authorization.AuthorizationFlags;
|
||||||
|
import eu.eudat.commons.enums.LockTargetType;
|
||||||
|
import eu.eudat.data.LockEntity;
|
||||||
|
import eu.eudat.model.Lock;
|
||||||
|
import gr.cite.tools.data.query.FieldResolver;
|
||||||
|
import gr.cite.tools.data.query.QueryBase;
|
||||||
|
import gr.cite.tools.data.query.QueryContext;
|
||||||
|
import jakarta.persistence.Tuple;
|
||||||
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class LockQuery extends QueryBase<LockEntity> {
|
||||||
|
|
||||||
|
private Collection<UUID> ids;
|
||||||
|
|
||||||
|
private Collection<UUID> targetIds;
|
||||||
|
|
||||||
|
private Collection<LockTargetType> targetTypes;
|
||||||
|
|
||||||
|
private Collection<UUID> excludedIds;
|
||||||
|
|
||||||
|
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||||
|
|
||||||
|
public LockQuery ids(UUID value) {
|
||||||
|
this.ids = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery ids(UUID... value) {
|
||||||
|
this.ids = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery ids(Collection<UUID> values) {
|
||||||
|
this.ids = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery targetIds(UUID value) {
|
||||||
|
this.targetIds = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery targetIds(UUID... value) {
|
||||||
|
this.targetIds = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery targetIds(Collection<UUID> values) {
|
||||||
|
this.targetIds = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery targetTypes(LockTargetType value) {
|
||||||
|
this.targetTypes = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery targetTypes(LockTargetType... value) {
|
||||||
|
this.targetTypes = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery targetTypes(Collection<LockTargetType> values) {
|
||||||
|
this.targetTypes = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery excludedIds(Collection<UUID> values) {
|
||||||
|
this.excludedIds = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery excludedIds(UUID value) {
|
||||||
|
this.excludedIds = List.of(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery excludedIds(UUID... value) {
|
||||||
|
this.excludedIds = Arrays.asList(value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery authorize(EnumSet<AuthorizationFlags> values) {
|
||||||
|
this.authorize = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<LockEntity> entityClass() {
|
||||||
|
return LockEntity.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Boolean isFalseQuery() {
|
||||||
|
return this.isEmpty(this.ids) || this.isEmpty(this.targetIds) || this.isEmpty(this.excludedIds) || this.isEmpty(this.targetTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
|
||||||
|
List<Predicate> predicates = new ArrayList<>();
|
||||||
|
if (this.ids != null) {
|
||||||
|
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._id));
|
||||||
|
for (UUID item : this.ids)
|
||||||
|
inClause.value(item);
|
||||||
|
predicates.add(inClause);
|
||||||
|
}
|
||||||
|
if (this.targetIds != null) {
|
||||||
|
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._target));
|
||||||
|
for (UUID item : this.targetIds)
|
||||||
|
inClause.value(item);
|
||||||
|
predicates.add(inClause);
|
||||||
|
}
|
||||||
|
if (this.targetTypes != null) {
|
||||||
|
CriteriaBuilder.In<LockTargetType> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._targetType));
|
||||||
|
for (LockTargetType item : this.targetTypes)
|
||||||
|
inClause.value(item);
|
||||||
|
predicates.add(inClause);
|
||||||
|
}
|
||||||
|
if (this.excludedIds != null) {
|
||||||
|
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._id));
|
||||||
|
for (UUID item : this.excludedIds)
|
||||||
|
notInClause.value(item);
|
||||||
|
predicates.add(notInClause.not());
|
||||||
|
}
|
||||||
|
if (!predicates.isEmpty()) {
|
||||||
|
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||||
|
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LockEntity convert(Tuple tuple, Set<String> columns) {
|
||||||
|
LockEntity item = new LockEntity();
|
||||||
|
item.setId(QueryBase.convertSafe(tuple, columns, LockEntity._id, UUID.class));
|
||||||
|
item.setTarget(QueryBase.convertSafe(tuple, columns, LockEntity._target, UUID.class));
|
||||||
|
item.setTargetType(QueryBase.convertSafe(tuple, columns, LockEntity._targetType, LockTargetType.class));
|
||||||
|
item.setLockedBy(QueryBase.convertSafe(tuple, columns, LockEntity._lockedBy, UUID.class));
|
||||||
|
item.setLockedAt(QueryBase.convertSafe(tuple, columns, LockEntity._lockedAt, Instant.class));
|
||||||
|
item.setTouchedAt(QueryBase.convertSafe(tuple, columns, LockEntity._touchedAt, Instant.class));
|
||||||
|
item.setTenantId(QueryBase.convertSafe(tuple, columns, LockEntity._tenantId, UUID.class));
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String fieldNameOf(FieldResolver item) {
|
||||||
|
if (item.match(Lock._id)) return LockEntity._id;
|
||||||
|
else if (item.match(Lock._target)) return LockEntity._target;
|
||||||
|
else if (item.match(Lock._targetType)) return LockEntity._targetType;
|
||||||
|
else if (item.prefix(Lock._lockedBy)) return LockEntity._lockedBy;
|
||||||
|
else if (item.match(Lock._lockedAt)) return LockEntity._lockedAt;
|
||||||
|
else if (item.match(Lock._touchedAt)) return LockEntity._touchedAt;
|
||||||
|
else if (item.prefix(Lock._tenant)) return LockEntity._tenantId;
|
||||||
|
else if (item.match(Lock._hash)) return LockEntity._lockedAt;
|
||||||
|
else return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
package eu.eudat.query.lookup;
|
||||||
|
|
||||||
|
|
||||||
|
import eu.eudat.commons.enums.LockTargetType;
|
||||||
|
import eu.eudat.query.LockQuery;
|
||||||
|
import gr.cite.tools.data.query.Lookup;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class LockLookup extends Lookup {
|
||||||
|
|
||||||
|
private List<UUID> ids;
|
||||||
|
|
||||||
|
private List<UUID> targetIds;
|
||||||
|
|
||||||
|
private List<LockTargetType> targetTypes;
|
||||||
|
|
||||||
|
private List<UUID> excludedIds;
|
||||||
|
|
||||||
|
public List<UUID> getIds() {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIds(List<UUID> ids) {
|
||||||
|
this.ids = ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UUID> getTargetIds() {
|
||||||
|
return targetIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetIds(List<UUID> targetIds) {
|
||||||
|
this.targetIds = targetIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UUID> getExcludedIds() {
|
||||||
|
return excludedIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExcludedIds(List<UUID> excludeIds) {
|
||||||
|
this.excludedIds = excludeIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LockTargetType> getTargetTypes() {
|
||||||
|
return targetTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetTypes(List<LockTargetType> targetTypes) {
|
||||||
|
this.targetTypes = targetTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LockQuery enrich(QueryFactory queryFactory) {
|
||||||
|
LockQuery query = queryFactory.query(LockQuery.class);
|
||||||
|
if (this.ids != null) query.ids(this.ids);
|
||||||
|
if (this.targetIds != null) query.targetIds(this.targetIds);
|
||||||
|
if (this.targetTypes != null) query.targetTypes(this.targetTypes);
|
||||||
|
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
|
||||||
|
|
||||||
|
this.enrichCommon(query);
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package eu.eudat.service.lock;
|
||||||
|
|
||||||
|
import eu.eudat.model.Lock;
|
||||||
|
import eu.eudat.model.persist.LockPersist;
|
||||||
|
import eu.eudat.query.lookup.LockLookup;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
|
import gr.cite.tools.exception.MyValidationException;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public interface LockService {
|
||||||
|
|
||||||
|
Lock persist(LockPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException;
|
||||||
|
|
||||||
|
boolean isLocked(LockLookup lookup) throws InvalidApplicationException;
|
||||||
|
|
||||||
|
void unlock(LockLookup lookup) throws InvalidApplicationException;
|
||||||
|
|
||||||
|
void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException;
|
||||||
|
}
|
|
@ -0,0 +1,188 @@
|
||||||
|
package eu.eudat.service.lock;
|
||||||
|
|
||||||
|
import eu.eudat.authorization.AuthorizationFlags;
|
||||||
|
import eu.eudat.authorization.Permission;
|
||||||
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
|
import eu.eudat.convention.ConventionService;
|
||||||
|
import eu.eudat.data.LockEntity;
|
||||||
|
import eu.eudat.errorcode.ErrorThesaurusProperties;
|
||||||
|
import eu.eudat.model.Lock;
|
||||||
|
import eu.eudat.model.builder.LockBuilder;
|
||||||
|
import eu.eudat.model.deleter.LockDeleter;
|
||||||
|
import eu.eudat.model.persist.LockPersist;
|
||||||
|
import eu.eudat.query.LockQuery;
|
||||||
|
import eu.eudat.query.lookup.LockLookup;
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
|
import gr.cite.tools.data.builder.BuilderFactory;
|
||||||
|
import gr.cite.tools.data.deleter.DeleterFactory;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
|
import gr.cite.tools.exception.MyValidationException;
|
||||||
|
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import gr.cite.tools.logging.MapLogEntry;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class LockServiceImpl implements LockService {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(LockServiceImpl.class));
|
||||||
|
private final Comparator<LockEntity> compareByTouchedAt = Comparator.comparing(o -> o.getTouchedAt());
|
||||||
|
private final EntityManager entityManager;
|
||||||
|
private final UserScope userScope;
|
||||||
|
private final AuthorizationService authorizationService;
|
||||||
|
private final DeleterFactory deleterFactory;
|
||||||
|
private final BuilderFactory builderFactory;
|
||||||
|
private final QueryFactory queryFactory;
|
||||||
|
private final ConventionService conventionService;
|
||||||
|
private final MessageSource messageSource;
|
||||||
|
private final ErrorThesaurusProperties errors;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LockServiceImpl(
|
||||||
|
EntityManager entityManager,
|
||||||
|
UserScope userScope,
|
||||||
|
AuthorizationService authorizationService,
|
||||||
|
DeleterFactory deleterFactory,
|
||||||
|
BuilderFactory builderFactory,
|
||||||
|
QueryFactory queryFactory,
|
||||||
|
ConventionService conventionService,
|
||||||
|
MessageSource messageSource,
|
||||||
|
ErrorThesaurusProperties errors) {
|
||||||
|
this.entityManager = entityManager;
|
||||||
|
this.userScope = userScope;
|
||||||
|
this.authorizationService = authorizationService;
|
||||||
|
this.deleterFactory = deleterFactory;
|
||||||
|
this.builderFactory = builderFactory;
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.conventionService = conventionService;
|
||||||
|
this.messageSource = messageSource;
|
||||||
|
this.errors = errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Lock persist(LockPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException {
|
||||||
|
logger.debug(new MapLogEntry("persisting data").And("model", model).And("fields", fields));
|
||||||
|
|
||||||
|
this.authorizationService.authorizeForce(Permission.EditLock);
|
||||||
|
|
||||||
|
Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
|
||||||
|
|
||||||
|
LockEntity data;
|
||||||
|
if (isUpdate) {
|
||||||
|
data = this.entityManager.find(LockEntity.class, model.getId());
|
||||||
|
if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Lock.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||||
|
if (!data.getLockedBy().equals(this.userScope.getUserId())) throw new MyApplicationException("Is not locked by that user");
|
||||||
|
if (!this.conventionService.hashValue(data.getTouchedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
|
||||||
|
} else {
|
||||||
|
data = new LockEntity();
|
||||||
|
data.setId(UUID.randomUUID());
|
||||||
|
data.setLockedAt(Instant.now());
|
||||||
|
data.setLockedBy(this.userScope.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
|
data.setTarget(model.getTarget());
|
||||||
|
data.setTargetType(model.getTargetType());
|
||||||
|
data.setTouchedAt(Instant.now());
|
||||||
|
|
||||||
|
if (isUpdate) this.entityManager.merge(data);
|
||||||
|
else this.entityManager.persist(data);
|
||||||
|
|
||||||
|
this.entityManager.flush();
|
||||||
|
|
||||||
|
return this.builderFactory.builder(LockBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(BaseFieldSet.build(fields, Lock._id), data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocked(LockLookup lookup) throws InvalidApplicationException {
|
||||||
|
if (lookup !=null && lookup.getTargetIds() != null && lookup.getTargetIds().size() > 0){
|
||||||
|
LockQuery query = this.queryFactory.query(LockQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).targetIds(lookup.getTargetIds());
|
||||||
|
if (query.count() == 1) {
|
||||||
|
LockEntity lock = query.firstAs(lookup.getProject());
|
||||||
|
if (lock.getLockedBy().equals(this.userScope.getUserId())) {
|
||||||
|
lock.setTouchedAt(Instant.now());
|
||||||
|
this.entityManager.merge(lock);
|
||||||
|
this.entityManager.flush();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.forceUnlock(lookup) > 0;
|
||||||
|
} else if (query.count() > 1) {
|
||||||
|
this.forceUnlock(lookup);
|
||||||
|
return this.isLocked(lookup);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else{
|
||||||
|
throw new InvalidApplicationException("Wrong LockLookup");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long forceUnlock(LockLookup lookup) throws InvalidApplicationException {
|
||||||
|
|
||||||
|
LockQuery query = this.queryFactory.query(LockQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).targetIds(lookup.getTargetIds());
|
||||||
|
Long availableLocks = query.count();
|
||||||
|
long deletedLocks = 0L;
|
||||||
|
if (availableLocks > 0) {
|
||||||
|
List<LockEntity> locks = query.collectAs(lookup.getProject());
|
||||||
|
for (LockEntity lock : locks) {
|
||||||
|
if (new Date().getTime() - Date.from(lock.getTouchedAt()).getTime() > 120000) {
|
||||||
|
this.deleteAndSave(lock.getId());
|
||||||
|
deletedLocks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deletedLocks == 0) {
|
||||||
|
LockEntity recentLock = locks.stream().max(compareByTouchedAt).get();
|
||||||
|
for (LockEntity lock : locks) {
|
||||||
|
if (lock != recentLock) {
|
||||||
|
this.deleteAndSave(lock.getId());
|
||||||
|
deletedLocks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return availableLocks - deletedLocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unlock(LockLookup lookup) throws InvalidApplicationException {
|
||||||
|
|
||||||
|
LockQuery query = this.queryFactory.query(LockQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).targetIds(lookup.getTargetIds());
|
||||||
|
if (query.count() == 1) {
|
||||||
|
LockEntity lock = query.firstAs(lookup.getProject());
|
||||||
|
if (!lock.getLockedBy().equals(this.userScope.getUserId())) {
|
||||||
|
throw new InvalidApplicationException("Only the user who created that lock can delete it");
|
||||||
|
}
|
||||||
|
this.deleteAndSave(lock.getId());
|
||||||
|
} else if (query.count() > 1) {
|
||||||
|
List<LockEntity> locks = query.collectAs(lookup.getProject());
|
||||||
|
locks.stream().filter(lock -> lock.getLockedBy().equals(this.userScope.getUserIdSafe())).forEach(lock -> {
|
||||||
|
try {
|
||||||
|
this.deleteAndSave(lock.getId());
|
||||||
|
} catch (InvalidApplicationException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||||
|
logger.debug("deleting : {}", id);
|
||||||
|
|
||||||
|
this.authorizationService.authorizeForce(Permission.DeleteLock);
|
||||||
|
|
||||||
|
this.deleterFactory.deleter(LockDeleter.class).deleteAndSaveByIds(List.of(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
package eu.eudat.controllers;
|
|
||||||
|
|
||||||
import eu.eudat.authorization.Permission;
|
|
||||||
import eu.eudat.logic.managers.LockManager;
|
|
||||||
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
|
||||||
import eu.eudat.models.data.lock.Lock;
|
|
||||||
import eu.eudat.types.ApiMessageCode;
|
|
||||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@CrossOrigin
|
|
||||||
@RequestMapping(value = {"/api/lock/"})
|
|
||||||
public class LockController {
|
|
||||||
|
|
||||||
private LockManager lockManager;
|
|
||||||
private final AuthorizationService authorizationService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public LockController(LockManager lockManager, AuthorizationService authorizationService) {
|
|
||||||
this.lockManager = lockManager;
|
|
||||||
this.authorizationService = authorizationService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@RequestMapping(method = RequestMethod.GET, path = "target/status/{id}")
|
|
||||||
public @ResponseBody ResponseEntity<ResponseItem<Boolean>> getLocked(@PathVariable String id) throws Exception {
|
|
||||||
this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
|
||||||
|
|
||||||
boolean locked = this.lockManager.isLocked(id);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Boolean>().status(ApiMessageCode.SUCCESS_MESSAGE).message("locked").payload(locked));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, path = "target/unlock/{id}")
|
|
||||||
public @ResponseBody ResponseEntity<ResponseItem<String>> unlock(@PathVariable String id) throws Exception {
|
|
||||||
this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
|
||||||
|
|
||||||
this.lockManager.unlock(id);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<String>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload("Lock Removed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
@RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
|
|
||||||
public @ResponseBody ResponseEntity<ResponseItem<UUID>> createOrUpdate(@RequestBody Lock lock) throws Exception {
|
|
||||||
this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
|
||||||
|
|
||||||
eu.eudat.data.old.Lock result = this.lockManager.createOrUpdate(lock);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<UUID>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(result.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET, path = "target/{id}")
|
|
||||||
public @ResponseBody ResponseEntity<ResponseItem<Lock>> getSingle(@PathVariable String id) throws Exception {
|
|
||||||
this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
|
||||||
|
|
||||||
Lock lock = this.lockManager.getFromTarget(id);
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Lock>().status(ApiMessageCode.NO_MESSAGE).payload(lock));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
package eu.eudat.controllers.v2;
|
||||||
|
|
||||||
|
import eu.eudat.audit.AuditableAction;
|
||||||
|
import eu.eudat.authorization.AuthorizationFlags;
|
||||||
|
import eu.eudat.authorization.Permission;
|
||||||
|
import eu.eudat.data.LockEntity;
|
||||||
|
import eu.eudat.model.Lock;
|
||||||
|
import eu.eudat.model.builder.LockBuilder;
|
||||||
|
import eu.eudat.model.censorship.LockCensor;
|
||||||
|
import eu.eudat.model.persist.LockPersist;
|
||||||
|
import eu.eudat.model.result.QueryResult;
|
||||||
|
import eu.eudat.models.data.helpers.responses.ResponseItem;
|
||||||
|
import eu.eudat.query.LockQuery;
|
||||||
|
import eu.eudat.query.lookup.LockLookup;
|
||||||
|
import eu.eudat.service.lock.LockService;
|
||||||
|
import eu.eudat.types.ApiMessageCode;
|
||||||
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
|
import gr.cite.tools.auditing.AuditService;
|
||||||
|
import gr.cite.tools.data.builder.BuilderFactory;
|
||||||
|
import gr.cite.tools.data.censor.CensorFactory;
|
||||||
|
import gr.cite.tools.data.query.QueryFactory;
|
||||||
|
import gr.cite.tools.exception.MyApplicationException;
|
||||||
|
import gr.cite.tools.exception.MyForbiddenException;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
|
import gr.cite.tools.logging.LoggerService;
|
||||||
|
import gr.cite.tools.logging.MapLogEntry;
|
||||||
|
import gr.cite.tools.validation.MyValidate;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.MessageSource;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.crypto.BadPaddingException;
|
||||||
|
import javax.crypto.IllegalBlockSizeException;
|
||||||
|
import javax.crypto.NoSuchPaddingException;
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(path = {"api/lock"})
|
||||||
|
public class LockController {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(LockController.class));
|
||||||
|
|
||||||
|
private final BuilderFactory builderFactory;
|
||||||
|
|
||||||
|
private final AuditService auditService;
|
||||||
|
|
||||||
|
private final LockService lockService;
|
||||||
|
|
||||||
|
private final CensorFactory censorFactory;
|
||||||
|
|
||||||
|
private final QueryFactory queryFactory;
|
||||||
|
|
||||||
|
private final MessageSource messageSource;
|
||||||
|
private final AuthorizationService authorizationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public LockController(BuilderFactory builderFactory,
|
||||||
|
AuditService auditService,
|
||||||
|
LockService lockService,
|
||||||
|
CensorFactory censorFactory,
|
||||||
|
QueryFactory queryFactory,
|
||||||
|
MessageSource messageSource,
|
||||||
|
AuthorizationService authorizationService) {
|
||||||
|
this.builderFactory = builderFactory;
|
||||||
|
this.auditService = auditService;
|
||||||
|
this.lockService = lockService;
|
||||||
|
this.censorFactory = censorFactory;
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.messageSource = messageSource;
|
||||||
|
this.authorizationService = authorizationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("query")
|
||||||
|
public QueryResult<Lock> query(@RequestBody LockLookup lookup) throws MyApplicationException, MyForbiddenException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
|
||||||
|
logger.debug("querying {}", Lock.class.getSimpleName());
|
||||||
|
|
||||||
|
this.censorFactory.censor(LockCensor.class).censor(lookup.getProject(), null);
|
||||||
|
|
||||||
|
LockQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic);
|
||||||
|
List<LockEntity> data = query.collectAs(lookup.getProject());
|
||||||
|
List<Lock> models = this.builderFactory.builder(LockBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(lookup.getProject(), data);
|
||||||
|
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.Lock_Query, "lookup", lookup);
|
||||||
|
|
||||||
|
return new QueryResult(models, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("{id}")
|
||||||
|
public Lock get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||||
|
logger.debug(new MapLogEntry("retrieving" + Lock.class.getSimpleName()).And("id", id).And("fields", fieldSet));
|
||||||
|
|
||||||
|
this.censorFactory.censor(LockCensor.class).censor(fieldSet, null);
|
||||||
|
|
||||||
|
LockQuery query = this.queryFactory.query(LockQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).ids(id);
|
||||||
|
Lock model = this.builderFactory.builder(LockBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(fieldSet, query.firstAs(fieldSet));
|
||||||
|
if (model == null)
|
||||||
|
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Lock.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.Lock_Lookup, Map.ofEntries(
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("id", id),
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||||
|
));
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("persist")
|
||||||
|
@Transactional
|
||||||
|
public Lock persist(@MyValidate @RequestBody LockPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
|
||||||
|
logger.debug(new MapLogEntry("persisting" + Lock.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
|
||||||
|
this.censorFactory.censor(LockCensor.class).censor(fieldSet, null);
|
||||||
|
|
||||||
|
Lock persisted = this.lockService.persist(model, fieldSet);
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.Lock_Persist, Map.ofEntries(
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("model", model),
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||||
|
));
|
||||||
|
|
||||||
|
return persisted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("target/{id}")
|
||||||
|
public Lock getWithTarget(@PathVariable("id") UUID targetId, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||||
|
logger.debug(new MapLogEntry("retrieving" + Lock.class.getSimpleName()).And("targetId", targetId).And("fields", fieldSet));
|
||||||
|
|
||||||
|
this.censorFactory.censor(LockCensor.class).censor(fieldSet, null);
|
||||||
|
|
||||||
|
LockQuery query = this.queryFactory.query(LockQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).targetIds(targetId);
|
||||||
|
Lock model = this.builderFactory.builder(LockBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(fieldSet, query.firstAs(fieldSet));
|
||||||
|
if (model == null)
|
||||||
|
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{targetId, Lock.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.Lock_Lookup, Map.ofEntries(
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("targetId", targetId),
|
||||||
|
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
|
||||||
|
));
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@PostMapping("target/status/{id}")
|
||||||
|
public @ResponseBody ResponseEntity<ResponseItem<Boolean>> getLocked(@RequestBody LockLookup lookup) throws Exception {
|
||||||
|
this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
||||||
|
|
||||||
|
boolean locked = this.lockService.isLocked(lookup);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Boolean>().status(ApiMessageCode.SUCCESS_MESSAGE).message("locked").payload(locked));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@PostMapping("target/unlock/{id}")
|
||||||
|
public @ResponseBody ResponseEntity<ResponseItem<String>> unlock(@RequestBody LockLookup lookup) throws Exception {
|
||||||
|
this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
||||||
|
|
||||||
|
this.lockService.unlock(lookup);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<String>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload("Lock Removed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("{id}")
|
||||||
|
@Transactional
|
||||||
|
public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||||
|
logger.debug(new MapLogEntry("retrieving" + Lock.class.getSimpleName()).And("id", id));
|
||||||
|
|
||||||
|
this.lockService.deleteAndSave(id);
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.Lock_Delete, "id", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Transactional
|
||||||
|
// @RequestMapping(method = RequestMethod.GET, path = "target/status/{id}")
|
||||||
|
// public @ResponseBody ResponseEntity<ResponseItem<Boolean>> getLocked(@PathVariable String id) throws Exception {
|
||||||
|
// this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
||||||
|
//
|
||||||
|
// boolean locked = this.lockManager.isLocked(id);
|
||||||
|
// return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Boolean>().status(ApiMessageCode.SUCCESS_MESSAGE).message("locked").payload(locked));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Transactional
|
||||||
|
// @RequestMapping(method = RequestMethod.DELETE, path = "target/unlock/{id}")
|
||||||
|
// public @ResponseBody ResponseEntity<ResponseItem<String>> unlock(@PathVariable String id) throws Exception {
|
||||||
|
// this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
||||||
|
//
|
||||||
|
// this.lockManager.unlock(id);
|
||||||
|
// return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<String>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload("Lock Removed"));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Transactional
|
||||||
|
// @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
|
||||||
|
// public @ResponseBody ResponseEntity<ResponseItem<UUID>> createOrUpdate(@RequestBody Lock lock) throws Exception {
|
||||||
|
// this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
||||||
|
//
|
||||||
|
// eu.eudat.data.old.Lock result = this.lockManager.createOrUpdate(lock);
|
||||||
|
// return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<UUID>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(result.getId()));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @RequestMapping(method = RequestMethod.GET, path = "target/{id}")
|
||||||
|
// public @ResponseBody ResponseEntity<ResponseItem<Lock>> getSingle(@PathVariable String id) throws Exception {
|
||||||
|
// this.authorizationService.authorizeForce(Permission.AuthenticatedRole);
|
||||||
|
//
|
||||||
|
// Lock lock = this.lockManager.getFromTarget(id);
|
||||||
|
// return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<Lock>().status(ApiMessageCode.NO_MESSAGE).payload(lock));
|
||||||
|
// }
|
||||||
|
}
|
|
@ -634,3 +634,24 @@ permissions:
|
||||||
clients: [ ]
|
clients: [ ]
|
||||||
allowAnonymous: false
|
allowAnonymous: false
|
||||||
allowAuthenticated: false
|
allowAuthenticated: false
|
||||||
|
|
||||||
|
# Lock Permissions
|
||||||
|
BrowseLock:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
EditLock:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
DeleteLock:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
claims: [ ]
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
DO $$DECLARE
|
||||||
|
this_version CONSTANT varchar := '00.01.039';
|
||||||
|
BEGIN
|
||||||
|
PERFORM * FROM "DBVersion" WHERE version = this_version;
|
||||||
|
IF FOUND THEN RETURN; END IF;
|
||||||
|
|
||||||
|
DROP TABLE public."Lock";
|
||||||
|
|
||||||
|
CREATE TABLE public."Lock"
|
||||||
|
(
|
||||||
|
id uuid NOT NULL,
|
||||||
|
target uuid NOT NULL,
|
||||||
|
target_type smallint NOT NULL,
|
||||||
|
locked_by uuid NOT NULL,
|
||||||
|
locked_at timestamp without time zone NOT NULL,
|
||||||
|
touched_at timestamp without time zone,
|
||||||
|
tenant uuid,
|
||||||
|
CONSTRAINT "Lock_pkey" PRIMARY KEY (id),
|
||||||
|
CONSTRAINT "Lock_lockedby_fkey" FOREIGN KEY (locked_by)
|
||||||
|
REFERENCES public."User" (id) MATCH SIMPLE
|
||||||
|
ON UPDATE NO ACTION
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
NOT VALID,
|
||||||
|
CONSTRAINT "Lock_tenant_fkey" FOREIGN KEY (tenant)
|
||||||
|
REFERENCES public."Tenant" (id) MATCH SIMPLE
|
||||||
|
ON UPDATE NO ACTION
|
||||||
|
ON DELETE NO ACTION
|
||||||
|
NOT VALID
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.039', '2023-12-08 12:00:00.000000+02', now(), 'Drop old Lock Table and create New Lock table.');
|
||||||
|
|
||||||
|
END$$;
|
|
@ -0,0 +1,4 @@
|
||||||
|
export enum LockTargetType {
|
||||||
|
Dmp = 0,
|
||||||
|
Description = 1
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
import { Guid } from '@common/types/guid';
|
import { Guid } from '@common/types/guid';
|
||||||
import { UserInfoListingModel } from '../user/user-info-listing';
|
import { UserInfoListingModel } from '../user/user-info-listing';
|
||||||
|
import { LockTargetType } from '@app/core/common/enum/lock-target-type';
|
||||||
|
import { User } from '../user/user';
|
||||||
|
|
||||||
|
// old model
|
||||||
export class LockModel {
|
export class LockModel {
|
||||||
id: Guid;
|
id: Guid;
|
||||||
target: Guid;
|
target: Guid;
|
||||||
|
@ -16,3 +19,24 @@ export class LockModel {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface Lock{
|
||||||
|
id: Guid;
|
||||||
|
target: Guid;
|
||||||
|
targetType: LockTargetType;
|
||||||
|
lockedBy: User;
|
||||||
|
lockedAt: Date;
|
||||||
|
touchedAt: Date;
|
||||||
|
hash: String;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Persist
|
||||||
|
export interface LockPersist{
|
||||||
|
id: Guid;
|
||||||
|
target: Guid;
|
||||||
|
targetType: LockTargetType;
|
||||||
|
lockedBy: User;
|
||||||
|
hash: String;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { Lookup } from "@common/model/lookup";
|
||||||
|
import { Guid } from "@common/types/guid";
|
||||||
|
import { LockTargetType } from "../common/enum/lock-target-type";
|
||||||
|
|
||||||
|
export class LockLookup extends Lookup implements LockLookup {
|
||||||
|
ids: Guid[];
|
||||||
|
excludedIds: Guid[];
|
||||||
|
targetIds: Guid[];
|
||||||
|
targetTypes: LockTargetType[];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LockLookup {
|
||||||
|
ids: Guid[];
|
||||||
|
excludedIds: Guid[];
|
||||||
|
targetIds: Guid[];
|
||||||
|
targetTypes: LockTargetType[];
|
||||||
|
}
|
|
@ -1,34 +1,76 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { HttpHeaders, HttpClient } from '@angular/common/http';
|
import { HttpHeaders, HttpClient } from '@angular/common/http';
|
||||||
import { BaseHttpService } from '../http/base-http.service';
|
import { Observable, throwError } from 'rxjs';
|
||||||
import { environment } from 'environments/environment';
|
import { Lock, LockModel, LockPersist } from '@app/core/model/lock/lock.model';
|
||||||
import { Observable } from 'rxjs';
|
|
||||||
import { LockModel } from '@app/core/model/lock/lock.model';
|
|
||||||
import { ConfigurationService } from '../configuration/configuration.service';
|
import { ConfigurationService } from '../configuration/configuration.service';
|
||||||
|
import { BaseHttpV2Service } from '../http/base-http-v2.service';
|
||||||
|
import { FilterService } from '@common/modules/text-filter/filter-service';
|
||||||
|
import { LockLookup } from '@app/core/query/lock.lookup';
|
||||||
|
import { QueryResult } from '@common/model/query-result';
|
||||||
|
import { catchError } from 'rxjs/operators';
|
||||||
|
import { Guid } from '@common/types/guid';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LockService {
|
export class LockService {
|
||||||
|
|
||||||
private actionUrl: string;
|
|
||||||
private headers = new HttpHeaders();
|
private headers = new HttpHeaders();
|
||||||
|
|
||||||
constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) {
|
constructor(private http: BaseHttpV2Service, private configurationService: ConfigurationService, private filterService: FilterService) {
|
||||||
this.actionUrl = configurationService.server + 'lock/';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get apiBase(): string { return `${this.configurationService.server}lock`; }
|
||||||
|
|
||||||
|
query(q: LockLookup): Observable<QueryResult<Lock>> {
|
||||||
|
const url = `${this.apiBase}/query`;
|
||||||
|
return this.http.post<QueryResult<Lock>>(url, q).pipe(catchError((error: any) => throwError(error)));
|
||||||
|
}
|
||||||
|
|
||||||
|
getSingle(id: Guid, reqFields: string[] = []): Observable<Lock> {
|
||||||
|
const url = `${this.apiBase}/${id}`;
|
||||||
|
const options = { params: { f: reqFields } };
|
||||||
|
|
||||||
|
return this.http
|
||||||
|
.get<Lock>(url, options).pipe(
|
||||||
|
catchError((error: any) => throwError(error)));
|
||||||
|
}
|
||||||
|
|
||||||
|
persist(item: LockPersist): Observable<Lock> {
|
||||||
|
const url = `${this.apiBase}/persist`;
|
||||||
|
|
||||||
|
return this.http
|
||||||
|
.post<Lock>(url, item).pipe(
|
||||||
|
catchError((error: any) => throwError(error)));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(id: Guid): Observable<Lock> {
|
||||||
|
const url = `${this.apiBase}/${id}`;
|
||||||
|
|
||||||
|
return this.http
|
||||||
|
.delete<Lock>(url).pipe(
|
||||||
|
catchError((error: any) => throwError(error)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//ToDo change Parameters
|
||||||
checkLockStatus(id: string): Observable<boolean> {
|
checkLockStatus(id: string): Observable<boolean> {
|
||||||
return this.http.get(`${this.actionUrl}target/status/${id}`, { headers: this.headers });
|
return this.http.get(`${this.apiBase}/target/status/${id}`, { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ToDo change Parameters
|
||||||
unlockTarget(id: string): Observable<any> {
|
unlockTarget(id: string): Observable<any> {
|
||||||
return this.http.delete(`${this.actionUrl}target/unlock/${id}`, { headers: this.headers });
|
return this.http.delete(`${this.apiBase}/target/unlock/${id}`, { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
getSingle(id: string): Observable<LockModel> {
|
getSingleWithTarget(targetId: Guid, reqFields: string[] = []): Observable<Lock> {
|
||||||
return this.http.get(`${this.actionUrl}target/${id}`, { headers: this.headers });
|
const url = `${this.apiBase}/target/${targetId}`;
|
||||||
|
const options = { params: { f: reqFields } };
|
||||||
|
|
||||||
|
return this.http
|
||||||
|
.get<Lock>(url, options).pipe(
|
||||||
|
catchError((error: any) => throwError(error)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ToDo replace with persist function
|
||||||
createOrUpdate(lock: LockModel): Observable<string> {
|
createOrUpdate(lock: LockModel): Observable<string> {
|
||||||
return this.http.post(`${this.actionUrl}`, lock, { headers: this.headers });
|
return this.http.post(`${this.apiBase}`, lock, { headers: this.headers });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue