You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mi...@apache.org on 2022/09/01 11:39:13 UTC
[jackrabbit-oak] 01/01: OAK-9914 adding system property to control whether recovery should be started for unclosed azure archive directory
This is an automated email from the ASF dual-hosted git repository.
miroslav pushed a commit to branch read_only_recovery
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
commit 8e0ae9f1e1d3fa9cee9a0bdf9d5e65305f3eab51
Author: smiroslav <mi...@apache.org>
AuthorDate: Thu Sep 1 13:36:20 2022 +0200
OAK-9914 adding system property to control whether recovery should be started for unclosed azure archive directory
---
oak-lucene/pom.xml | 1 -
oak-parent/pom.xml | 6 ++
oak-search-elastic/pom.xml | 1 -
oak-segment-azure/pom.xml | 5 ++
.../oak/segment/azure/AzureArchiveManager.java | 4 +-
.../oak/segment/azure/AzureArchiveManagerTest.java | 64 ++++++++++++++++++++++
6 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/oak-lucene/pom.xml b/oak-lucene/pom.xml
index f9a4986e80..cff61286a9 100644
--- a/oak-lucene/pom.xml
+++ b/oak-lucene/pom.xml
@@ -448,7 +448,6 @@
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
- <version>1.19.0</version>
<scope>test</scope>
</dependency>
diff --git a/oak-parent/pom.xml b/oak-parent/pom.xml
index 3ef7bb9722..52459c1ff7 100644
--- a/oak-parent/pom.xml
+++ b/oak-parent/pom.xml
@@ -781,6 +781,12 @@
<version>1</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.github.stefanbirkner</groupId>
+ <artifactId>system-rules</artifactId>
+ <version>1.19.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
diff --git a/oak-search-elastic/pom.xml b/oak-search-elastic/pom.xml
index 25a910eb02..72d18a745c 100644
--- a/oak-search-elastic/pom.xml
+++ b/oak-search-elastic/pom.xml
@@ -348,7 +348,6 @@
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
- <version>1.19.0</version>
<scope>test</scope>
</dependency>
diff --git a/oak-segment-azure/pom.xml b/oak-segment-azure/pom.xml
index 73391f8eab..b86ce5478e 100644
--- a/oak-segment-azure/pom.xml
+++ b/oak-segment-azure/pom.xml
@@ -224,6 +224,11 @@
<version>1.0.9</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.github.stefanbirkner</groupId>
+ <artifactId>system-rules</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
diff --git a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java
index 7e2d28b9e8..0f3b4751e4 100644
--- a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java
+++ b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java
@@ -56,6 +56,8 @@ public class AzureArchiveManager implements SegmentArchiveManager {
private static final Logger log = LoggerFactory.getLogger(AzureSegmentArchiveReader.class);
+ private boolean skipArchiveClosedCheck = Boolean.getBoolean("segment.azure.skipArchiveClosedCheck");
+
protected final CloudBlobDirectory cloudBlobDirectory;
protected final IOMonitor ioMonitor;
@@ -110,7 +112,7 @@ public class AzureArchiveManager implements SegmentArchiveManager {
public SegmentArchiveReader open(String archiveName) throws IOException {
try {
CloudBlobDirectory archiveDirectory = getDirectory(archiveName);
- if (!archiveDirectory.getBlockBlobReference("closed").exists()) {
+ if (!skipArchiveClosedCheck && !archiveDirectory.getBlockBlobReference("closed").exists()) {
throw new IOException("The archive " + archiveName + " hasn't been closed correctly.");
}
return new AzureSegmentArchiveReader(archiveDirectory, ioMonitor);
diff --git a/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java b/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java
index 1a97334a10..c165c207c2 100644
--- a/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java
+++ b/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java
@@ -29,6 +29,7 @@ import org.apache.jackrabbit.oak.segment.SegmentNotFoundException;
import org.apache.jackrabbit.oak.segment.file.FileStore;
import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
import org.apache.jackrabbit.oak.segment.file.InvalidFileStoreVersionException;
+import org.apache.jackrabbit.oak.segment.file.ReadOnlyFileStore;
import org.apache.jackrabbit.oak.segment.spi.RepositoryNotReachableException;
import org.apache.jackrabbit.oak.segment.spi.monitor.FileStoreMonitorAdapter;
import org.apache.jackrabbit.oak.segment.spi.monitor.IOMonitorAdapter;
@@ -42,7 +43,10 @@ import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.rules.TestRule;
import java.io.File;
import java.io.FileNotFoundException;
@@ -69,6 +73,9 @@ public class AzureArchiveManagerTest {
private CloudBlobContainer container;
+ @Rule
+ public final TestRule restoreSystemProperties = new RestoreSystemProperties();
+
@Before
public void setup() throws StorageException, InvalidKeyException, URISyntaxException {
container = azurite.getContainer("oak-test");
@@ -321,4 +328,61 @@ public class AzureArchiveManagerTest {
// SegmentNotFoundException should be thrown here
fileStore.readSegment(new SegmentId(fileStore, u.getMostSignificantBits(), u.getLeastSignificantBits()));
}
+
+ @Test
+ public void testReadOnlyWithoutRecovery() throws URISyntaxException, InvalidFileStoreVersionException, IOException, CommitFailedException, StorageException {
+
+ AzurePersistence rwPersistence = new AzurePersistence(container.getDirectoryReference("oak"));
+ FileStore rwFileStore = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(rwPersistence).build();
+ SegmentNodeStore segmentNodeStore = SegmentNodeStoreBuilders.builder(rwFileStore).build();
+ NodeBuilder builder = segmentNodeStore.getRoot().builder();
+ builder.setProperty("foo", "bar");
+ segmentNodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+ rwFileStore.flush();
+
+ assertTrue(container.getDirectoryReference("oak/data00000a.tar").listBlobs().iterator().hasNext());
+ assertFalse(container.getDirectoryReference("oak/data00000a.tar.ro.bak").listBlobs().iterator().hasNext());
+
+ // set the system property so that the check if archive dir is closed is skipped
+ System.setProperty("segment.azure.skipArchiveClosedCheck", "true");
+
+ // create read-only FS
+ AzurePersistence roPersistence = new AzurePersistence(container.getDirectoryReference("oak"));
+ ReadOnlyFileStore roFileStore = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(roPersistence).buildReadOnly();
+
+ roFileStore.close();
+ rwFileStore.close();
+
+ assertTrue(container.getDirectoryReference("oak/data00000a.tar").listBlobs().iterator().hasNext());
+ // after creating a read-only FS, the recovery procedure should not be started since there is another running Oak process
+ assertFalse(container.getDirectoryReference("oak/data00000a.tar.ro.bak").listBlobs().iterator().hasNext());
+
+ }
+
+ @Test
+ public void testReadOnlyWithRecovery() throws URISyntaxException, InvalidFileStoreVersionException, IOException, CommitFailedException, StorageException {
+
+ AzurePersistence rwPersistence = new AzurePersistence(container.getDirectoryReference("oak"));
+ FileStore rwFileStore = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(rwPersistence).build();
+ SegmentNodeStore segmentNodeStore = SegmentNodeStoreBuilders.builder(rwFileStore).build();
+ NodeBuilder builder = segmentNodeStore.getRoot().builder();
+ builder.setProperty("foo", "bar");
+ segmentNodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+ rwFileStore.flush();
+
+ assertTrue(container.getDirectoryReference("oak/data00000a.tar").listBlobs().iterator().hasNext());
+ assertFalse(container.getDirectoryReference("oak/data00000a.tar.ro.bak").listBlobs().iterator().hasNext());
+
+ // create read-only FS
+ AzurePersistence roPersistence = new AzurePersistence(container.getDirectoryReference("oak"));
+ ReadOnlyFileStore roFileStore = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(roPersistence).buildReadOnly();
+
+ roFileStore.close();
+ rwFileStore.close();
+
+ assertTrue(container.getDirectoryReference("oak/data00000a.tar").listBlobs().iterator().hasNext());
+ // after creating a read-only FS, the recovery procedure has happened started since there is another running Oak process
+ // and the last archive is not closed
+ assertTrue(container.getDirectoryReference("oak/data00000a.tar.ro.bak").listBlobs().iterator().hasNext());
+ }
}