diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java index 70955fa05783..0e665167283d 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java @@ -657,6 +657,13 @@ private LockDataProviderInitResult initialize( currentIteratedSnapshotId, snapId, toResolveSnapshotId)); } UUID previousId = previousIds.iterator().next(); + // If the previousId is null and if toResolveSnapshotId is not null then should throw an exception since + // the snapshot can never be resolved against the toResolveSnapshotId. + if (previousId == null) { + throw new IOException(String.format( + "Snapshot %s versions previousId is null thus %s cannot be resolved against id %s", + currentIteratedSnapshotId, snapId, toResolveSnapshotId)); + } HierarchicalResourceLock previousToPreviousReadLockAcquired = acquireLock(previousId, true); try { // Get the version node for the snapshot and update the version node to the successor to point to the @@ -705,6 +712,12 @@ private LockDataProviderInitResult initialize( // Set the previous snapshot version to the relativePreviousVersionNode which was captured. versionMeta.setPreviousSnapshotVersion(relativePreviousVersionNode.getVersion()); } + } else if (toResolveSnapshotId != null) { + // If the previousId is null and if toResolveSnapshotId is not null then should throw an exception since + // the snapshot can never be resolved against the toResolveSnapshotId. + throw new IOException(String.format("Unable to resolve previous snapshot id for snapshot: %s against " + + "previous snapshotId : %s since current snapshot's previousSnapshotId is null", + snapId, toResolveSnapshotId)); } else { toResolveSnapshotId = null; ssLocalData.setPreviousSnapshotId(null); diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java index 9aa56d2dd027..e3b5d343b368 100644 --- a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java @@ -685,7 +685,7 @@ public void testVersionResolution(boolean read) throws IOException { addVersionsToLocalData(localDataManager, snapshotIds.get(i), versionMaps.get(i)); } for (int start = 0; start < snapshotIds.size(); start++) { - for (int end = start + 1; end < snapshotIds.size(); end++) { + for (int end = 0; end < snapshotIds.size(); end++) { UUID prevSnapId = snapshotIds.get(start); UUID snapId = snapshotIds.get(end); Map versionMap = new HashMap<>(versionMaps.get(end)); @@ -695,19 +695,29 @@ public void testVersionResolution(boolean read) throws IOException { version.setValue(versionMaps.get(idx).getOrDefault(version.getValue(), 0)); } } - try (ReadableOmSnapshotLocalDataProvider snap = read ? - localDataManager.getOmSnapshotLocalData(snapId, prevSnapId) : - localDataManager.getWritableOmSnapshotLocalData(snapId, prevSnapId)) { - OmSnapshotLocalData snapshotLocalData = snap.getSnapshotLocalData(); - OmSnapshotLocalData prevSnapshotLocalData = snap.getPreviousSnapshotLocalData(); - assertEquals(prevSnapshotLocalData.getSnapshotId(), snapshotLocalData.getPreviousSnapshotId()); - assertEquals(prevSnapId, snapshotLocalData.getPreviousSnapshotId()); - assertEquals(snapId, snapshotLocalData.getSnapshotId()); - assertTrue(snapshotLocalData.getVersionSstFileInfos().size() > 1); - snapshotLocalData.getVersionSstFileInfos() - .forEach((version, versionMeta) -> { - assertEquals(versionMap.get(version), versionMeta.getPreviousSnapshotVersion()); - }); + if (start >= end) { + assertThrows(IOException.class, () -> { + if (read) { + localDataManager.getOmSnapshotLocalData(snapId, prevSnapId); + } else { + localDataManager.getWritableOmSnapshotLocalData(snapId, prevSnapId); + } + }); + } else { + try (ReadableOmSnapshotLocalDataProvider snap = read ? + localDataManager.getOmSnapshotLocalData(snapId, prevSnapId) : + localDataManager.getWritableOmSnapshotLocalData(snapId, prevSnapId)) { + OmSnapshotLocalData snapshotLocalData = snap.getSnapshotLocalData(); + OmSnapshotLocalData prevSnapshotLocalData = snap.getPreviousSnapshotLocalData(); + assertEquals(prevSnapshotLocalData.getSnapshotId(), snapshotLocalData.getPreviousSnapshotId()); + assertEquals(prevSnapId, snapshotLocalData.getPreviousSnapshotId()); + assertEquals(snapId, snapshotLocalData.getSnapshotId()); + assertTrue(snapshotLocalData.getVersionSstFileInfos().size() > 1); + snapshotLocalData.getVersionSstFileInfos() + .forEach((version, versionMeta) -> { + assertEquals(versionMap.get(version), versionMeta.getPreviousSnapshotVersion()); + }); + } } } }