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..cc6b21a991 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 @@ -42,6 +42,7 @@ import java.util.EnumSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.Set; import java.util.regex.Matcher; @@ -50,6 +51,8 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.Maps.newHashMap; import static org.apache.jackrabbit.oak.segment.azure.AzureUtilities.getName; public class AzureArchiveManager implements SegmentArchiveManager { @@ -97,6 +100,29 @@ public class AzureArchiveManager implements SegmentArchiveManager { } } + private static final Pattern FILE_NAME_PATTERN = Pattern.compile("(data)((0|[1-9][0-9]*)[0-9]{4})([a-z])?.tar"); + private static Map> collectFiles(SegmentArchiveManager archiveManager) throws IOException { + Map> dataFiles = newHashMap(); + for (String file : archiveManager.listArchives()) { + Matcher matcher = FILE_NAME_PATTERN.matcher(file); + if (matcher.matches()) { + Integer index = Integer.parseInt(matcher.group(2)); + Map files = dataFiles.get(index); + if (files == null) { + files = newHashMap(); + dataFiles.put(index, files); + } + Character generation = 'a'; + if (matcher.group(4) != null) { + generation = matcher.group(4).charAt(0); + } + checkState(files.put(generation, file) == null); + } + } + return dataFiles; + } + + /** * Check if there's a valid 0000. segment in the archive * @param archiveName @@ -111,7 +137,18 @@ public class AzureArchiveManager implements SegmentArchiveManager { try { CloudBlobDirectory archiveDirectory = getDirectory(archiveName); if (!archiveDirectory.getBlockBlobReference("closed").exists()) { - throw new IOException("The archive " + archiveName + " hasn't been closed correctly."); + + Map> archiveFiles = collectFiles(this); + Matcher matcher = FILE_NAME_PATTERN.matcher(archiveName); + + if (matcher.matches()) { + Integer archiveIndex = Integer.parseInt(matcher.group(2)); + // check if current archive is the latest one + if (archiveIndex != Collections.max(archiveFiles.keySet())) { + throw new IOException("The archive " + archiveName + " hasn't been closed correctly."); + } + } + } return new AzureSegmentArchiveReader(archiveDirectory, ioMonitor); } catch (StorageException | URISyntaxException e) {