From a8fa0312d1fe706d1ea626bd616b03a3ddb709be Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Fri, 14 Feb 2020 10:35:19 +0200 Subject: [PATCH] Fix issue when multiple locks are in DB --- .../eu/eudat/logic/managers/LockManager.java | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/LockManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/LockManager.java index 4d2a21419..46a900e3e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/LockManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/LockManager.java @@ -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 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,31 +50,47 @@ 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; } - 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(); - this.apiContext.getOperationsContext().getDatabaseRepository().getLockDao().delete(lock); + List 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 {