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 to...@apache.org on 2019/08/21 09:55:09 UTC

svn commit: r1865615 - in /jackrabbit/oak/trunk/oak-segment-azure/src: main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java

Author: tomekr
Date: Wed Aug 21 09:55:08 2019
New Revision: 1865615

URL: http://svn.apache.org/viewvc?rev=1865615&view=rev
Log:
OAK-8566: Empty segment archives breaks the Azure Persistence

Modified:
    jackrabbit/oak/trunk/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java
    jackrabbit/oak/trunk/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java

Modified: jackrabbit/oak/trunk/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java?rev=1865615&r1=1865614&r2=1865615&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java (original)
+++ jackrabbit/oak/trunk/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManager.java Wed Aug 21 09:55:08 2019
@@ -37,6 +37,7 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.EnumSet;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.UUID;
@@ -67,7 +68,7 @@ public class AzureArchiveManager impleme
     @Override
     public List<String> listArchives() throws IOException {
         try {
-            return StreamSupport.stream(cloudBlobDirectory
+            List<String> archiveNames = StreamSupport.stream(cloudBlobDirectory
                     .listBlobs(null, false, EnumSet.noneOf(BlobListingDetails.class), null, null)
                     .spliterator(), false)
                     .filter(i -> i instanceof CloudBlobDirectory)
@@ -78,11 +79,30 @@ public class AzureArchiveManager impleme
                     .map(Path::getFileName)
                     .map(Path::toString)
                     .collect(Collectors.toList());
+
+            Iterator<String> it = archiveNames.iterator();
+            while (it.hasNext()) {
+                String archiveName = it.next();
+                if (isArchiveEmpty(archiveName)) {
+                    delete(archiveName);
+                    it.remove();
+                }
+            }
+            return archiveNames;
         } catch (URISyntaxException | StorageException e) {
             throw new IOException(e);
         }
     }
 
+    /**
+     * Check if there's a valid 0000. segment in the archive
+     * @param archiveName
+     * @return true if the archive is empty (no 0000.* segment)
+     */
+    private boolean isArchiveEmpty(String archiveName) throws IOException, URISyntaxException, StorageException {
+        return !getDirectory(archiveName).listBlobs("0000.").iterator().hasNext();
+    }
+
     @Override
     public SegmentArchiveReader open(String archiveName) throws IOException {
         try {

Modified: jackrabbit/oak/trunk/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java?rev=1865615&r1=1865614&r2=1865615&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-azure/src/test/java/org/apache/jackrabbit/oak/segment/azure/AzureArchiveManagerTest.java Wed Aug 21 09:55:08 2019
@@ -17,7 +17,9 @@
 package org.apache.jackrabbit.oak.segment.azure;
 
 import com.microsoft.azure.storage.StorageException;
+import com.microsoft.azure.storage.blob.CloudBlob;
 import com.microsoft.azure.storage.blob.CloudBlobContainer;
+import com.microsoft.azure.storage.blob.ListBlobItem;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.segment.SegmentNodeStore;
 import org.apache.jackrabbit.oak.segment.SegmentNodeStoreBuilders;
@@ -98,6 +100,36 @@ public class AzureArchiveManagerTest {
 
         fs = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(p).build();
         segmentNodeStore = SegmentNodeStoreBuilders.builder(fs).build();
+        assertEquals("bar", segmentNodeStore.getRoot().getString("foo"));
+        fs.close();
+    }
+
+    @Test
+    // see OAK-8566
+    public void testUncleanStopWithEmptyArchive() throws URISyntaxException, IOException, InvalidFileStoreVersionException, CommitFailedException, StorageException {
+        AzurePersistence p = new AzurePersistence(container.getDirectoryReference("oak"));
+        FileStore fs = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(p).build();
+        SegmentNodeStore segmentNodeStore = SegmentNodeStoreBuilders.builder(fs).build();
+        NodeBuilder builder = segmentNodeStore.getRoot().builder();
+        builder.setProperty("foo", "bar");
+        segmentNodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        fs.close();
+
+        // make sure there are 2 archives
+        fs = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(p).build();
+        segmentNodeStore = SegmentNodeStoreBuilders.builder(fs).build();
+        builder = segmentNodeStore.getRoot().builder();
+        builder.setProperty("foo2", "bar2");
+        segmentNodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        fs.close();
+
+        // remove the segment 0000 from the second archive
+        ListBlobItem segment0000 = container.listBlobs("oak/data00001a.tar/0000.").iterator().next();
+        ((CloudBlob) segment0000).delete();
+        container.getBlockBlobReference("oak/data00001a.tar/closed").delete();
+
+        fs = FileStoreBuilder.fileStoreBuilder(new File("target")).withCustomPersistence(p).build();
+        segmentNodeStore = SegmentNodeStoreBuilders.builder(fs).build();
         assertEquals("bar", segmentNodeStore.getRoot().getString("foo"));
         fs.close();
     }