Fix issue when multiple locks are in DB

This commit is contained in:
George Kalampokis 2020-02-14 10:35:19 +02:00
parent 2b41ca582f
commit a8fa0312d1
1 changed files with 29 additions and 10 deletions

View File

@ -9,11 +9,14 @@ import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.persistence.NoResultException;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Component
public class LockManager {
private final Comparator<eu.eudat.data.entities.Lock> compareByTouchedAt = Comparator.comparing(o -> o.getTouchedAt().getTime());
private ApiContext apiContext;
private Environment environment;
@ -34,7 +37,7 @@ public class LockManager {
}
}
}catch(NoResultException e) {
return new eu.eudat.data.entities.Lock();
lock.setId(null);
}
}
eu.eudat.data.entities.Lock newLock = lock.toDataModel();
@ -47,32 +50,48 @@ public class LockManager {
LockCriteria criteria = new LockCriteria();
criteria.setTarget(UUID.fromString(targetId));
Long availableLocks = this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().getWithCriteria(criteria).count();
if (availableLocks > 0) {
if (availableLocks == 1) {
eu.eudat.data.entities.Lock lock = this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().getWithCriteria(criteria).getSingle();
if (lock.getLockedBy().getId().equals(principal.getId())) {
lock.setTouchedAt(new Date());
this.createOrUpdate(new Lock().fromDataModel(lock), principal);
return false;
}
if (new Date().getTime() - lock.getTouchedAt().getTime() > environment.getProperty("database.lock-fail-interval", Integer.class)) {
this.forceUnlock(targetId);
return false;
}
if (this.forceUnlock(targetId) > 0){
return true;
}
} else if (availableLocks > 1) {
this.forceUnlock(targetId);
return this.isLocked(targetId, principal);
}
return false;
}
private void forceUnlock(String targetId) throws Exception {
private Long forceUnlock(String targetId) {
LockCriteria criteria = new LockCriteria();
criteria.setTarget(UUID.fromString(targetId));
Long availableLocks = this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().getWithCriteria(criteria).count();
Long deletedLocks = 0L;
if (availableLocks > 0) {
eu.eudat.data.entities.Lock lock = this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().getWithCriteria(criteria).getSingle();
List<eu.eudat.data.entities.Lock> locks = this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().getWithCriteria(criteria).toList();
for (eu.eudat.data.entities.Lock lock : locks) {
if (new Date().getTime() - lock.getTouchedAt().getTime() > environment.getProperty("database.lock-fail-interval", Integer.class)) {
this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().delete(lock);
deletedLocks++;
}
}
if (deletedLocks == 0) {
eu.eudat.data.entities.Lock recentlock = locks.stream().max(compareByTouchedAt).get();
for (eu.eudat.data.entities.Lock lock : locks) {
if (lock != recentlock) {
this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().delete(lock);
deletedLocks++;
}
}
}
}
return availableLocks - deletedLocks;
}
public void unlock(String targetId, Principal principal) throws Exception {
LockCriteria criteria = new LockCriteria();