/** * Unlocks all locks corresponding to the tokens held by the supplied session. * * @throws RepositoryException if the session is not live */ final void cleanLocks() throws RepositoryException { // clean the session-scoped locks: unlock all the nodes and remove the lock tokens from the system area Set<String> cleanedTokens = lockManager.cleanLocks(session); if (lockTokens.isEmpty()) { return; } // clean all open-scoped locks created via this session for (String lockToken : lockTokens) { if (!cleanedTokens.contains(lockToken)) { ModeShapeLock lock = lockManager.findLockByToken(lockToken); if (lock == null) { // there is no existing lock for this token (it must've been removed from somewhere else) continue; } // this is an open-scoped lock created via this session for which we'll have to update the 'held' flag if (!lockManager.setHeldBySession(session, lockToken, false)) { // Generally not expected, because if the lock exists we can always change the lock-held value to false // even when it is already false ... throw new LockException(JcrI18n.invalidLockToken.text(lockToken)); } } } // always clean our internal map of tokens lockTokens.clear(); }
/** * Determine if this lock manager holds a lock on the supplied node. * * @param node the node; may not be null * @return true if this lock maanger does hold a lock on the node, or false otherwise */ public boolean holdsLock( AbstractJcrNode node ) { return lockManager.findLockFor(node.key()) != null; }
protected ModeShapeLock( NodeKey lockKey, Map<Name, Property> properties ) { this.lockKey = lockKey; this.lockedNodeKey = lockedNodeKeyFromLockKey(lockKey); this.workspaceName = firstString(properties.get(ModeShapeLexicon.WORKSPACE)); this.lockOwner = firstString(properties.get(JcrLexicon.LOCK_OWNER)); this.deep = firstBoolean(properties.get(JcrLexicon.LOCK_IS_DEEP)); this.sessionScoped = firstBoolean(properties.get(ModeShapeLexicon.IS_SESSION_SCOPED)); this.lockToken = firstString(properties.get(ModeShapeLexicon.LOCK_TOKEN)); this.lockingSessionId = firstString(properties.get(ModeShapeLexicon.LOCKING_SESSION)); this.expiryTime = firstDate(properties.get(ModeShapeLexicon.EXPIRATION_DATE)); }
SystemContent system = new SystemContent(systemSession); NodeKey nodeKey = node.getKey(); NodeKey lockKey = generateLockKey(system.locksKey(), nodeKey); String token = generateLockToken(); ModeShapeLock lock = new ModeShapeLock(nodeKey, lockKey, session.workspaceName(), owner, token, isDeep, isSessionScoped, session.sessionId(), expirationDate); CachedNode locked = findLockedNodeAtOrBelow(node, cache); if (locked != null) { String nodePath = session.stringFactory().create(node.getPath(cache)); if (existing != null) { if (!existing.isExpired()) { throwAlreadyLocked(session, existing); unlock(session, existing.lockedNodeKey); throwAlreadyLocked(session, existing);
this.internalWorkerContext = other.internalWorkerContext; this.nodeTypes = other.nodeTypes.with(this, true, true); this.lockManager = other.lockManager.with(this, other.config.getGarbageCollection()); this.lockManager = new RepositoryLockManager(this, config.getGarbageCollection()); this.changeBus.register(this.lockManager); this.lockManager.refreshFromSystem(); if (!this.nodeTypes.refreshFromSystem()) { try {
public void unlock( AbstractJcrNode node ) throws PathNotFoundException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException { if (node.isModified()) { throw new InvalidItemStateException(JcrI18n.changedNodeCannotBeUnlocked.text(node.getPath())); } ModeShapeLock lock = lockManager.findLockFor(node.key()); if (lock != null && !lockTokens.contains(lock.getLockToken())) { // Someone else holds the lock, so see if the user has the permission to break someone else's lock ... try { session.checkPermission(session.workspaceName(), node.path(), ModeShapePermissions.UNLOCK_ANY); } catch (AccessDeniedException e) { //expected by the TCK throw new LockException(e); } } // Remove the lock ... String lockToken = lockManager.unlock(session, node.key()); lockTokens.remove(lockToken); }
@Test @FixFor( "MODE-2450" ) public void shouldCleanupCorruptedLocks() throws Exception { final AbstractJcrNode testNode = session.getRootNode().addNode("test"); final String path = testNode.getPath(); testNode.addMixin("mix:lockable"); session.save(); final org.modeshape.jcr.RepositoryLockManager.Lock lock = (RepositoryLockManager.Lock) session.getWorkspace().getLockManager().lock(path, false, false, Long.MAX_VALUE, session.getUserID()); Assert.assertNotNull(lock); session.logout(); //forcibly remove the lock node from the system area... String lockKey = lock.lockKey().toString(); assertTrue(runInTransaction(() -> repository.documentStore().remove(lockKey))); //and then force a refresh RepositoryLockManager lockManager = repository.lockManager(); lockManager.refreshFromSystem(); //check that the lock has been removed session = repository.login(); assertFalse(session.getWorkspace().getLockManager().isLocked("/test")); // issue another refresh and verify the node is still unlocked lockManager.refreshFromSystem(); assertFalse(session.getWorkspace().getLockManager().isLocked("/test")); }
RepositoryLockManager with( JcrRepository.RunningState repository, RepositoryConfiguration.GarbageCollection gcConfig ) { assert this.systemWorkspaceName == repository.repositoryCache().getSystemWorkspaceName(); assert this.processId == repository.context().getProcessId(); PathFactory pathFactory = repository.context().getValueFactories().getPathFactory(); Path locksPath = pathFactory.create(pathFactory.createRootPath(), JcrLexicon.SYSTEM, ModeShapeLexicon.LOCKS); assert this.locksPath.equals(locksPath); return new RepositoryLockManager(repository, gcConfig); }
@Override public String[] getLockTokens() { Set<String> tokens = new HashSet<String>(); for (String token : lockTokens) { ModeShapeLock lock = lockManager.findLockByToken(token); if (lock != null && !lock.isSessionScoped()) { tokens.add(token); } } return tokens.toArray(new String[tokens.size()]); }
.map(JcrSession::sessionId) .collect(Collectors.toSet()); this.lockManager().cleanupLocks(activeSessionIds); if (logger.isDebugEnabled()) { logger.debug("Finishing lock cleanup in the '{0}' repository", repositoryName());
DateTime expirationDate = firstDate(lockNode.getProperty(ModeShapeLexicon.EXPIRATION_DATE, systemSession)); if (expirationDate.isBefore(now)) {
SystemContent system = new SystemContent(systemSession); NodeKey nodeKey = node.getKey(); NodeKey lockKey = generateLockKey(system.locksKey(), nodeKey); String token = generateLockToken(); ModeShapeLock lock = new ModeShapeLock(nodeKey, lockKey, session.workspaceName(), owner, token, isDeep, isSessionScoped, session.sessionId(), expirationDate); CachedNode locked = findLockedNodeAtOrBelow(node, cache); if (locked != null) { String nodePath = session.stringFactory().create(node.getPath(cache)); if (existing != null) { if (!existing.isExpired()) { throwAlreadyLocked(session, existing); unlock(session, existing.lockedNodeKey); throwAlreadyLocked(session, existing);
this.internalWorkerContext = other.internalWorkerContext; this.nodeTypes = other.nodeTypes.with(this, true, true); this.lockManager = other.lockManager.with(this, other.config.getGarbageCollection()); this.lockManager = new RepositoryLockManager(this, config.getGarbageCollection()); this.changeBus.register(this.lockManager); this.lockManager.refreshFromSystem(); if (!this.nodeTypes.refreshFromSystem()) { try {
public void unlock( AbstractJcrNode node ) throws PathNotFoundException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException { if (node.isModified()) { throw new InvalidItemStateException(JcrI18n.changedNodeCannotBeUnlocked.text(node.getPath())); } ModeShapeLock lock = lockManager.findLockFor(node.key()); if (lock != null && !lockTokens.contains(lock.getLockToken())) { // Someone else holds the lock, so see if the user has the permission to break someone else's lock ... try { session.checkPermission(session.workspaceName(), node.path(), ModeShapePermissions.UNLOCK_ANY); } catch (AccessDeniedException e) { //expected by the TCK throw new LockException(e); } } // Remove the lock ... String lockToken = lockManager.unlock(session, node.key()); lockTokens.remove(lockToken); }
RepositoryLockManager with( JcrRepository.RunningState repository, RepositoryConfiguration.GarbageCollection gcConfig ) { assert this.systemWorkspaceName == repository.repositoryCache().getSystemWorkspaceName(); assert this.processId == repository.context().getProcessId(); PathFactory pathFactory = repository.context().getValueFactories().getPathFactory(); Path locksPath = pathFactory.create(pathFactory.createRootPath(), JcrLexicon.SYSTEM, ModeShapeLexicon.LOCKS); assert this.locksPath.equals(locksPath); return new RepositoryLockManager(repository, gcConfig); }
@Override public String[] getLockTokens() { Set<String> tokens = new HashSet<String>(); for (String token : lockTokens) { ModeShapeLock lock = lockManager.findLockByToken(token); if (lock != null && !lock.isSessionScoped()) { tokens.add(token); } } return tokens.toArray(new String[tokens.size()]); }
.map(JcrSession::sessionId) .collect(Collectors.toSet()); this.lockManager().cleanupLocks(activeSessionIds); if (logger.isDebugEnabled()) { logger.debug("Finishing lock cleanup in the '{0}' repository", repositoryName());
DateTime expirationDate = firstDate(lockNode.getProperty(ModeShapeLexicon.EXPIRATION_DATE, systemSession)); if (expirationDate.isBefore(now)) {
protected ModeShapeLock( NodeKey lockKey, Map<Name, Property> properties ) { this.lockKey = lockKey; this.lockedNodeKey = lockedNodeKeyFromLockKey(lockKey); this.workspaceName = firstString(properties.get(ModeShapeLexicon.WORKSPACE)); this.lockOwner = firstString(properties.get(JcrLexicon.LOCK_OWNER)); this.deep = firstBoolean(properties.get(JcrLexicon.LOCK_IS_DEEP)); this.sessionScoped = firstBoolean(properties.get(ModeShapeLexicon.IS_SESSION_SCOPED)); this.lockToken = firstString(properties.get(ModeShapeLexicon.LOCK_TOKEN)); this.lockingSessionId = firstString(properties.get(ModeShapeLexicon.LOCKING_SESSION)); this.expiryTime = firstDate(properties.get(ModeShapeLexicon.EXPIRATION_DATE)); }
/** * Unlocks all locks corresponding to the tokens held by the supplied session. * * @throws RepositoryException if the session is not live */ final void cleanLocks() throws RepositoryException { // clean the session-scoped locks: unlock all the nodes and remove the lock tokens from the system area Set<String> cleanedTokens = lockManager.cleanLocks(session); if (lockTokens.isEmpty()) { return; } // clean all open-scoped locks created via this session for (String lockToken : lockTokens) { if (!cleanedTokens.contains(lockToken)) { ModeShapeLock lock = lockManager.findLockByToken(lockToken); if (lock == null) { // there is no existing lock for this token (it must've been removed from somewhere else) continue; } // this is an open-scoped lock created via this session for which we'll have to update the 'held' flag if (!lockManager.setHeldBySession(session, lockToken, false)) { // Generally not expected, because if the lock exists we can always change the lock-held value to false // even when it is already false ... throw new LockException(JcrI18n.invalidLockToken.text(lockToken)); } } } // always clean our internal map of tokens lockTokens.clear(); }