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:12 UTC

[jackrabbit-oak] branch read_only_recovery created (now 8e0ae9f1e1)

This is an automated email from the ASF dual-hosted git repository.

miroslav pushed a change to branch read_only_recovery
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


      at 8e0ae9f1e1 OAK-9914 adding system property to control whether recovery should be started for unclosed azure archive directory

This branch includes the following new commits:

     new 8e0ae9f1e1 OAK-9914 adding system property to control whether recovery should be started for unclosed azure archive directory

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[jackrabbit-oak] 01/01: OAK-9914 adding system property to control whether recovery should be started for unclosed azure archive directory

Posted by mi...@apache.org.
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());
+    }
 }