Add rollback logic to restore deleted files when move fails

This commit is contained in:
aditya.chandel
2025-11-25 05:30:12 -07:00
parent e0e1938f2f
commit aa07f5ee74
2 changed files with 40 additions and 2 deletions

View File

@@ -31,10 +31,37 @@ public class FileMoveHelper {
if (target.getParent() != null) {
Files.createDirectories(target.getParent());
}
log.info("Moving file from {} to {}", source, target);
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
}
public Path moveFileWithBackup(Path source, Path target) throws IOException {
Path tempPath = source.resolveSibling(source.getFileName().toString() + ".tmp_move");
log.info("Moving file from {} to temporary location {}", source, tempPath);
Files.move(source, tempPath, StandardCopyOption.REPLACE_EXISTING);
return tempPath;
}
public void commitMove(Path tempPath, Path target) throws IOException {
if (target.getParent() != null) {
Files.createDirectories(target.getParent());
}
log.info("Committing move from temporary location {} to {}", tempPath, target);
Files.move(tempPath, target, StandardCopyOption.REPLACE_EXISTING);
}
public void rollbackMove(Path tempPath, Path originalSource) {
if (Files.exists(tempPath)) {
try {
log.info("Rolling back move from {} to {}", tempPath, originalSource);
Files.move(tempPath, originalSource, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
log.error("Failed to rollback file move from {} to {}", tempPath, originalSource, e);
}
}
}
public String extractSubPath(Path filePath, LibraryPathEntity libraryPathEntity) {
Path libraryRoot = Paths.get(libraryPathEntity.getPath()).toAbsolutePath().normalize();
Path parentDir = filePath.getParent().toAbsolutePath().normalize();

View File

@@ -50,6 +50,9 @@ public class FileMoveService {
Long targetLibraryId = move.getTargetLibraryId();
Long targetLibraryPathId = move.getTargetLibraryPathId();
Path tempPath = null;
Path currentFilePath = null;
try {
Optional<BookEntity> optionalBook = bookRepository.findById(bookId);
Optional<LibraryEntity> optionalLibrary = libraryRepository.findById(targetLibraryId);
@@ -70,18 +73,22 @@ public class FileMoveService {
monitoringRegistrationService.unregisterLibraries(Collections.singleton(sourceLibrary.getId()));
sourceLibraryIds.add(sourceLibrary.getId());
}
Path currentFilePath = bookEntity.getFullFilePath();
currentFilePath = bookEntity.getFullFilePath();
String pattern = fileMoveHelper.getFileNamingPattern(targetLibrary);
Path newFilePath = fileMoveHelper.generateNewFilePath(bookEntity, libraryPathEntity, pattern);
if (currentFilePath.equals(newFilePath)) {
continue;
}
fileMoveHelper.moveFile(currentFilePath, newFilePath);
tempPath = fileMoveHelper.moveFileWithBackup(currentFilePath, newFilePath);
String newFileName = newFilePath.getFileName().toString();
String newFileSubPath = fileMoveHelper.extractSubPath(newFilePath, libraryPathEntity);
bookRepository.updateFileAndLibrary(bookEntity.getId(), newFileSubPath, newFileName, targetLibrary.getId(), libraryPathEntity);
fileMoveHelper.commitMove(tempPath, newFilePath);
tempPath = null;
Path libraryRoot = Paths.get(bookEntity.getLibraryPath().getPath()).toAbsolutePath().normalize();
fileMoveHelper.deleteEmptyParentDirsUpToLibraryFolders(currentFilePath.getParent(), Set.of(libraryRoot));
@@ -93,6 +100,10 @@ public class FileMoveService {
} catch (Exception e) {
log.error("Error moving file for book ID {}: {}", bookId, e.getMessage(), e);
} finally {
if (tempPath != null && currentFilePath != null) {
fileMoveHelper.rollbackMove(tempPath, currentFilePath);
}
}
}