summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin/kbackupfabric/util/backup
diff options
context:
space:
mode:
authorKeuin <[email protected]>2021-01-13 17:47:20 +0800
committerkeuin <[email protected]>2021-01-13 17:47:20 +0800
commite0c6a21fe9bfb01237fd145064f0af309879a9fb (patch)
tree321955f96030213c2bc8c3ec350961a81b60edee /src/main/java/com/keuin/kbackupfabric/util/backup
parent2bc659d8f95a97d0514491e48ed9c66828a4e308 (diff)
Incremental backup now works (tested, but not thoroughly)
Diffstat (limited to 'src/main/java/com/keuin/kbackupfabric/util/backup')
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java9
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactory.java15
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java43
-rw-r--r--src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java2
4 files changed, 61 insertions, 8 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java b/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java
index c1aa5fe..837b638 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/BackupFilesystemUtil.java
@@ -14,7 +14,8 @@ import java.util.regex.Pattern;
*/
public final class BackupFilesystemUtil {
- private static final String backupSaveDirectoryName = "backups";
+ private static final String BACKUP_SAVE_DIRECTORY_NAME = "backups";
+ private static final String INCREMENTAL_BASE_DIRECTORY_NAME = "incremental";
private static final String backupFileNamePrefix = "kbackup-";
@Deprecated
@@ -43,7 +44,11 @@ public final class BackupFilesystemUtil {
}
public static File getBackupSaveDirectory(MinecraftServer server) {
- return new File(server.getRunDirectory(), backupSaveDirectoryName);
+ return new File(server.getRunDirectory(), BACKUP_SAVE_DIRECTORY_NAME);
+ }
+
+ public static File getIncrementalBackupBaseDirectory(MinecraftServer server) {
+ return new File(server.getRunDirectory(), INCREMENTAL_BASE_DIRECTORY_NAME);
}
public static String getLevelPath(MinecraftServer server) {
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactory.java b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactory.java
index 627cb5c..2f3761c 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactory.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/ObjectCollectionFactory.java
@@ -1,5 +1,6 @@
package com.keuin.kbackupfabric.util.backup.incremental;
+import com.keuin.kbackupfabric.util.PrintUtil;
import com.keuin.kbackupfabric.util.backup.incremental.identifier.FileIdentifierProvider;
import com.keuin.kbackupfabric.util.backup.incremental.identifier.ObjectIdentifier;
@@ -23,26 +24,32 @@ public class ObjectCollectionFactory<T extends ObjectIdentifier> {
this.identifierFactory = identifierFactory;
}
- public ObjectCollection fromDirectory(File directory) throws IOException {
+ public ObjectCollection fromDirectory(File directory, Set<String> ignoredFiles) throws IOException {
final Set<ObjectElement> subFiles = new HashSet<>();
final Map<String, ObjectCollection> subCollections = new HashMap<>();
if (!Objects.requireNonNull(directory).isDirectory())
throw new IllegalArgumentException("given file is not a directory");
- for (Iterator<Path> iter = Files.walk(directory.toPath(), 1).iterator(); iter.hasNext();) {
+ for (Iterator<Path> iter = Files.walk(directory.toPath(), 1).iterator(); iter.hasNext(); ) {
Path path = iter.next();
if (Files.isSameFile(path, directory.toPath()))
continue;
File file = path.toFile();
if (file.isDirectory()) {
- subCollections.put(file.getName(), fromDirectory(file));
- } else {
+ subCollections.put(file.getName(), fromDirectory(file, ignoredFiles));
+ } else if (!ignoredFiles.contains(file.getName())) {
subFiles.add(new ObjectElement(file.getName(), identifierFactory.fromFile(file)));
+ } else {
+ PrintUtil.info(String.format("Skipping file %s.", file.getName()));
}
}
return new ObjectCollection(directory.getName(), subFiles, subCollections);
}
+ public ObjectCollection fromDirectory(File directory) throws IOException {
+ return fromDirectory(directory, Collections.emptySet());
+ }
+
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java
index cd15499..a4271c6 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/incremental/manager/IncrementalBackupStorageManager.java
@@ -1,9 +1,11 @@
package com.keuin.kbackupfabric.util.backup.incremental.manager;
+import com.keuin.kbackupfabric.util.PrintUtil;
import com.keuin.kbackupfabric.util.backup.incremental.ObjectCollection;
import com.keuin.kbackupfabric.util.backup.incremental.ObjectElement;
import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -11,6 +13,8 @@ import java.nio.file.Paths;
import java.util.Map;
import java.util.Objects;
+import static org.apache.commons.io.FileUtils.forceDelete;
+
public class IncrementalBackupStorageManager {
private final Path backupStorageBase;
@@ -63,13 +67,50 @@ public class IncrementalBackupStorageManager {
int copyCount = 0;
+ // touch directory
+ if (!collectionBasePath.exists()) {
+ int retryCounter = 0;
+ boolean success = false;
+ while (retryCounter++ < 5) {
+ if (collectionBasePath.mkdirs()) {
+ success = true;
+ break;
+ }
+ }
+ if (!success) {
+ throw new IOException("Failed to create directory " + collectionBasePath.getAbsolutePath());
+ }
+ }
+
// copy sub files
for (Map.Entry<String, ObjectElement> entry : collection.getElementMap().entrySet()) {
File copySource = new File(backupStorageBase.toFile(), entry.getValue().getIdentifier().getIdentification());
+ File copyTarget = new File(collectionBasePath.getAbsolutePath(), entry.getKey());
+
if (!baseContainsObject(entry.getValue())) {
throw new IOException(String.format("File %s does not exist in the base.", copySource.getName()));
}
- Files.copy(copySource.toPath(), Paths.get(collectionBasePath.getAbsolutePath(), entry.getKey()));
+ if (copyTarget.exists()) {
+ boolean successDeleting = false;
+ for (int i = 0; i < 5; ++i) {
+ try {
+ forceDelete(copyTarget);
+ successDeleting = true;
+ break;
+ } catch (FileNotFoundException ignored) {
+ break;
+ } catch (IOException e) {
+ PrintUtil.error(String.format("Failed to delete file %s, retry.", copyTarget.getName()));
+ }
+ }
+ if (!successDeleting) {
+ String msg = String.format("Failed to delete file %s.", copyTarget.getName());
+ PrintUtil.error(msg);
+ throw new IOException(msg);
+ }
+ }
+
+ Files.copy(copySource.toPath(), copyTarget.toPath());
++copyCount;
}
diff --git a/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java b/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java
index a0d4128..3c35201 100644
--- a/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java
+++ b/src/main/java/com/keuin/kbackupfabric/util/backup/name/IncrementalBackupFileNameEncoder.java
@@ -6,7 +6,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IncrementalBackupFileNameEncoder implements BackupFileNameEncoder {
- private static final String backupFileNamePrefix = "incremental-";
+ private static final String backupFileNamePrefix = "incremental";
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
// TODO: make this private and use singleton pattern