diff --git a/server/src/main/java/org/opensearch/index/store/RemoteSegmentStoreDirectory.java b/server/src/main/java/org/opensearch/index/store/RemoteSegmentStoreDirectory.java index c7f72d50055a8..530e1f090b51d 100644 --- a/server/src/main/java/org/opensearch/index/store/RemoteSegmentStoreDirectory.java +++ b/server/src/main/java/org/opensearch/index/store/RemoteSegmentStoreDirectory.java @@ -377,6 +377,11 @@ public IndexInput openInput(String name, IOContext context) throws IOException { @Override public void acquireLock(LockInfo lockInfo) throws IOException { assert lockInfo instanceof FileLockInfo : "lockInfo should be instance of FileLockInfo"; + String filename = ((FileLockInfo) lockInfo).getFileToLock(); + Collection metadataFiles = remoteMetadataDirectory.listFilesByPrefix(filename); + if (metadataFiles.isEmpty()) { + throw new NoSuchFileException("Metadata file " + filename + " does not exist to acquire lock"); + } IndexOutput indexOutput = remoteLockDirectory.createOutput(lockInfo.generateLockName(), IOContext.DEFAULT); indexOutput.close(); } @@ -385,13 +390,16 @@ public void acquireLock(LockInfo lockInfo) throws IOException { * Releases a lock which was acquired on given segment commit. * @param lockInfo lock identifier and acquirer ID info * @throws IOException will be thrown in case i) listing lock files failed or ii) deleting the lock file failed. - * @throws NoSuchFileException when metadata file is not present for given commit point. */ @Override public void releaseLock(LockInfo lockInfo) throws IOException { assert lockInfo instanceof FileLockInfo : "lockInfo should be instance of FileLockInfo"; Collection lockFiles = remoteLockDirectory.listFilesByPrefix(((FileLockInfo) lockInfo).getLockPrefix()); + if (lockFiles.isEmpty()) { + logger.warn("Lock file {} does not exist", ((FileLockInfo) lockInfo).getFileToLock()); + return; + } // ideally there should be only one lock per acquirer, but just to handle any stale locks, // we try to release all the locks for the acquirer. List locksToRelease = ((FileLockInfo) lockInfo).getLocksForAcquirer(lockFiles.toArray(String[]::new)); diff --git a/server/src/test/java/org/opensearch/index/store/RemoteSegmentStoreDirectoryTests.java b/server/src/test/java/org/opensearch/index/store/RemoteSegmentStoreDirectoryTests.java index 8f489239f6ea0..597fac1d14f26 100644 --- a/server/src/test/java/org/opensearch/index/store/RemoteSegmentStoreDirectoryTests.java +++ b/server/src/test/java/org/opensearch/index/store/RemoteSegmentStoreDirectoryTests.java @@ -405,11 +405,8 @@ public void testAcquireLock() throws IOException { long testGeneration = 5; List metadataFiles = List.of("metadata__1__5__abc"); - when( - remoteMetadataDirectory.listFilesByPrefix( - RemoteSegmentStoreDirectory.MetadataFilenameUtils.getMetadataFilePrefixForCommit(testPrimaryTerm, testGeneration) - ) - ).thenReturn(metadataFiles); + when(remoteMetadataDirectory.listFilesByPrefix(RemoteSegmentStoreDirectory.MetadataFilenameUtils.getMetadataFilePrefixForCommit(testPrimaryTerm, testGeneration))).thenReturn(metadataFiles); + when(remoteMetadataDirectory.listFilesByPrefix(remoteSegmentStoreDirectory.getLockIdentifier(testPrimaryTerm, testGeneration))).thenReturn(metadataFiles); IndexOutput indexOutput = mock(IndexOutput.class); when(remoteLockDirectory.createOutput(any(), eq(IOContext.DEFAULT))).thenReturn(indexOutput); @@ -429,13 +426,17 @@ public void testAcquireLock() throws IOException { public void testAcquireLockNoSuchFile() throws IOException { populateMetadata(); remoteSegmentStoreDirectory.init(); - String testAcquirerId = "test-acquirer"; - long testPrimaryTerm = 2; - long testGeneration = 3; + String acquirerId = "test-acquirer"; + long testPrimaryTerm = 1; + long testGeneration = 5; + + List metadataFiles = List.of("metadata__1__5__abc"); + when(remoteMetadataDirectory.listFilesByPrefix(RemoteSegmentStoreDirectory.MetadataFilenameUtils.getMetadataFilePrefixForCommit(testPrimaryTerm, testGeneration))).thenReturn(metadataFiles); + when(remoteMetadataDirectory.listFilesByPrefix(remoteSegmentStoreDirectory.getLockIdentifier(testPrimaryTerm, testGeneration))).thenReturn(List.of()); LockInfo lockInfo = FileLockInfo.getLockInfoBuilder() .withFileToLock(remoteSegmentStoreDirectory.getLockIdentifier(testPrimaryTerm, testGeneration)) - .withAcquirerId(testAcquirerId) + .withAcquirerId(acquirerId) .build(); assertThrows(NoSuchFileException.class, () -> remoteSegmentStoreDirectory.acquireLock(lockInfo)); }