summaryrefslogtreecommitdiff
path: root/src/main/java/com/keuin
diff options
context:
space:
mode:
authorKeuin <[email protected]>2021-01-25 02:07:54 +0800
committerkeuin <[email protected]>2021-01-25 02:12:53 +0800
commit43d48aa979a1e316af5ba0445412fe8926ce983b (patch)
treeae1419a6c09d286e3604d52bd6f86e807bfbd98d /src/main/java/com/keuin
parent1df50093bd76315905a9aae880470e81b5e1d8f0 (diff)
Perform clean-up after deleting a backup.
Diffstat (limited to 'src/main/java/com/keuin')
-rw-r--r--src/main/java/com/keuin/kbackupfabric/KBCommands.java3
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollection2.java5
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionSerializer.java76
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java25
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/IncBackupInfoSerializer.java4
-rw-r--r--src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/SavedIncBackupV1.java4
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java71
-rw-r--r--src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java2
8 files changed, 112 insertions, 78 deletions
diff --git a/src/main/java/com/keuin/kbackupfabric/KBCommands.java b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
index 9c887fd..01231be 100644
--- a/src/main/java/com/keuin/kbackupfabric/KBCommands.java
+++ b/src/main/java/com/keuin/kbackupfabric/KBCommands.java
@@ -407,8 +407,9 @@ public final class KBCommands {
return "(Incremental) " + info.getBackupName()
+ ", " + DateUtil.getString(info.getBackupTime())
+ ((info.getTotalSizeBytes() > 0) ?
- ("size: " + BackupFilesystemUtil.getFriendlyFileSizeString(info.getTotalSizeBytes())) : "");
+ (" size: " + BackupFilesystemUtil.getFriendlyFileSizeString(info.getTotalSizeBytes())) : "");
} catch (IOException e) {
+ e.printStackTrace();
return "(Incremental) " + backupFile.getName();
}
}
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollection2.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollection2.java
index 8d8eb14..7a198af 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollection2.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollection2.java
@@ -3,12 +3,9 @@ package com.keuin.kbackupfabric.backup.incremental;
import java.io.Serializable;
import java.util.*;
-/**
- * This class must be in package `com.keuin.kbackupfabric.util.backup.incremental.ObjectCollection`,
- * or it will not be compatible with old backups.
- */
public class ObjectCollection2 implements Serializable {
+ private static final long serialVersionUID = 6651743898782813296L;
private final String name;
private final Map<String, ObjectElement> elements;
private final Map<String, ObjectCollection2> subCollections;
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionSerializer.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionSerializer.java
index fa411a0..3be1bfe 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionSerializer.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/ObjectCollectionSerializer.java
@@ -1,11 +1,17 @@
package com.keuin.kbackupfabric.backup.incremental;
-import org.jetbrains.annotations.NotNull;
+import com.keuin.kbackupfabric.backup.incremental.serializer.IncBackupInfoSerializer;
+import com.keuin.kbackupfabric.backup.incremental.serializer.SavedIncrementalBackup;
-import java.io.*;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Objects;
/**
@@ -19,17 +25,18 @@ public class ObjectCollectionSerializer {
*/
@Deprecated
public static ObjectCollection2 fromFile(File file) throws IOException {
- Objects.requireNonNull(file);
- ObjectCollection2 collection;
- try (FileInputStream fileInputStream = new FileInputStream(file)) {
- try (ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
- collection = (ObjectCollection2) objectInputStream.readObject();
- } catch (ClassNotFoundException ignored) {
- // this should not happen
- return null;
- }
- }
- return collection;
+ throw new RuntimeException("This method has been depreciated.");
+// Objects.requireNonNull(file);
+// ObjectCollection2 collection;
+// try (FileInputStream fileInputStream = new FileInputStream(file)) {
+// try (ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream)) {
+// collection = (ObjectCollection2) objectInputStream.readObject();
+// } catch (ClassNotFoundException ignored) {
+// // this should not happen
+// return null;
+// }
+// }
+// return collection;
}
/**
@@ -46,38 +53,19 @@ public class ObjectCollectionSerializer {
}
public static Iterable<ObjectCollection2> fromDirectory(File directory) throws IOException {
-
if (!directory.isDirectory()) {
throw new IllegalArgumentException("Given directory is invalid.");
}
- return new Iterable<ObjectCollection2>() {
- private final Iterator<ObjectCollection2> iter = new Iterator<ObjectCollection2>() {
- private final Iterator<Path> i = Files.walk(directory.toPath(), 1).filter(p -> {
- File f = p.toFile();
- return f.isFile() && f.getName().endsWith(".kbi");
- }).iterator();
-
- @Override
- public boolean hasNext() {
- return i.hasNext();
- }
-
- @Override
- public ObjectCollection2 next() {
- try {
- return fromFile(i.next().toFile());
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- };
-
- @NotNull
- @Override
- public Iterator<ObjectCollection2> iterator() {
- return iter;
- }
- };
-
+ List<Path> pathList = new ArrayList<>();
+ Files.walk(directory.toPath(), 1).filter(p -> {
+ File f = p.toFile();
+ return f.isFile() && f.getName().endsWith(".kbi");
+ }).forEach(pathList::add);
+ List<ObjectCollection2> objectList = new ArrayList<>();
+ for (Path path : pathList) {
+ SavedIncrementalBackup info = IncBackupInfoSerializer.fromFile(path.toFile());
+ objectList.add(info.getObjectCollection());
+ }
+ return Collections.unmodifiableCollection(objectList);
}
}
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java
index ad7287f..0a99bf0 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/manager/IncrementalBackupStorageManager.java
@@ -14,6 +14,7 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import static org.apache.commons.io.FileUtils.forceDelete;
@@ -76,32 +77,38 @@ public class IncrementalBackupStorageManager {
/**
* Delete all files in the specific collection, from the storage base.
*
- * @param collection the collection containing files to be deleted.
- * @param collectionBasePath the collection base path.
+ * @param collection the collection containing files to be deleted.
+ * @return files deleted
* @throws IOException I/O error.
*/
- public void deleteObjectCollection(ObjectCollection2 collection, File collectionBasePath) throws IOException {
- deleteObjectCollection(collection, collectionBasePath, Collections.emptySet());
+ public int deleteObjectCollection(ObjectCollection2 collection) throws IOException {
+ return deleteObjectCollection(collection, Collections.emptySet());
}
/**
* Delete a collection from the storage base, optionally preserving files used by other backups.
*
* @param collection the collection containing files to be deleted.
- * @param collectionBasePath the collection base path.
* @param otherExistingCollections other collections (not to be deleted) in this base. Files exist in these collections will not be deleted.
+ * @return files deleted
*/
- public void deleteObjectCollection(ObjectCollection2 collection, File collectionBasePath,
- Iterable<ObjectCollection2> otherExistingCollections) {
+ public int deleteObjectCollection(ObjectCollection2 collection,
+ Iterable<ObjectCollection2> otherExistingCollections) {
Iterator<ObjectElement> iter = new ObjectCollectionIterator(collection);
Set<ObjectElement> unusedElementSet = new HashSet<>();
iter.forEachRemaining(unusedElementSet::add);
otherExistingCollections.forEach(col -> new ObjectCollectionIterator(col).forEachRemaining(unusedElementSet::remove));
+ AtomicInteger deleteCount = new AtomicInteger();
unusedElementSet.forEach(ele -> {
File file = new File(backupStorageBase.toFile(), ele.getIdentifier().getIdentification());
- if (!file.delete())
- LOGGER.warning("Failed to delete unused file " + file.getName());
+ if (file.exists()) {
+ if (file.delete())
+ deleteCount.incrementAndGet();
+ else
+ LOGGER.warning("Failed to delete unused file " + file.getName());
+ }
});
+ return deleteCount.get();
}
/**
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/IncBackupInfoSerializer.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/IncBackupInfoSerializer.java
index d084aef..e79c02f 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/IncBackupInfoSerializer.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/IncBackupInfoSerializer.java
@@ -41,8 +41,12 @@ public class IncBackupInfoSerializer {
}
} catch (ClassNotFoundException e) {
// this should not happen
+ e.printStackTrace();
throw new RuntimeException(e);
}
+ } catch (Exception e) {
+ System.err.println("Failed to deserialize file " + file.getName());
+ throw e;
}
}
diff --git a/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/SavedIncBackupV1.java b/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/SavedIncBackupV1.java
index bd2d4eb..e34efdb 100644
--- a/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/SavedIncBackupV1.java
+++ b/src/main/java/com/keuin/kbackupfabric/backup/incremental/serializer/SavedIncBackupV1.java
@@ -6,10 +6,12 @@ import com.keuin.kbackupfabric.util.DateUtil;
import java.io.Serializable;
import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.Objects;
public class SavedIncBackupV1 implements SavedIncrementalBackup, Serializable {
+ private static final long serialVersionUID = 5798490056955510205L;
private final ObjectCollection2 objectCollection2;
private final String backupName;
private final ZonedDateTime backupTime;
@@ -17,6 +19,8 @@ public class SavedIncBackupV1 implements SavedIncrementalBackup, Serializable {
private final long increasedSizeBytes;
private final int filesAdded;
private final int totalFiles;
+ // this field is depreciated and kept only for serialization compatibility
+ private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");
public SavedIncBackupV1(ObjectCollection2 objectCollection2, String backupName, ZonedDateTime backupTime, long totalSizeBytes, long increasedSizeBytes, int filesAdded, int totalFiles) {
this.totalFiles = totalFiles;
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java b/src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java
index 7ebff0a..7bfb0b7 100644
--- a/src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java
+++ b/src/main/java/com/keuin/kbackupfabric/operation/DeleteOperation.java
@@ -1,5 +1,11 @@
package com.keuin.kbackupfabric.operation;
+import com.keuin.kbackupfabric.backup.BackupFilesystemUtil;
+import com.keuin.kbackupfabric.backup.incremental.ObjectCollection2;
+import com.keuin.kbackupfabric.backup.incremental.ObjectCollectionSerializer;
+import com.keuin.kbackupfabric.backup.incremental.manager.IncrementalBackupStorageManager;
+import com.keuin.kbackupfabric.backup.incremental.serializer.IncBackupInfoSerializer;
+import com.keuin.kbackupfabric.backup.incremental.serializer.SavedIncrementalBackup;
import com.keuin.kbackupfabric.backup.suggestion.BackupNameSuggestionProvider;
import com.keuin.kbackupfabric.operation.abstracts.InvokableAsyncBlockingOperation;
import com.keuin.kbackupfabric.util.PrintUtil;
@@ -9,15 +15,17 @@ import net.minecraft.server.command.ServerCommandSource;
import java.io.File;
import java.io.IOException;
+import java.util.logging.Logger;
import static com.keuin.kbackupfabric.backup.BackupFilesystemUtil.getBackupSaveDirectory;
+import static com.keuin.kbackupfabric.backup.BackupFilesystemUtil.getIncrementalBackupBaseDirectory;
import static com.keuin.kbackupfabric.util.PrintUtil.msgErr;
import static com.keuin.kbackupfabric.util.PrintUtil.msgInfo;
import static org.apache.commons.io.FileUtils.forceDelete;
public class DeleteOperation extends InvokableAsyncBlockingOperation {
- //private static final Logger LOGGER = LogManager.getLogger();
+ private static final Logger LOGGER = Logger.getLogger(DeleteOperation.class.getName());
private final String backupFileName;
private final CommandContext<ServerCommandSource> context;
@@ -39,25 +47,50 @@ public class DeleteOperation extends InvokableAsyncBlockingOperation {
}
private void delete() {
- MinecraftServer server = context.getSource().getMinecraftServer();
- PrintUtil.info("Deleting backup file " + this.backupFileName);
- File backupFile = new File(getBackupSaveDirectory(server), backupFileName);
- int tryCounter = 0;
- do {
- if (tryCounter == 5) {
- String msg = "Failed to delete file " + backupFileName;
- PrintUtil.error(msg);
- msgErr(context, msg);
- return;
+ try {
+ MinecraftServer server = context.getSource().getMinecraftServer();
+ PrintUtil.info("Deleting backup file " + this.backupFileName);
+ File backupFile = new File(getBackupSaveDirectory(server), backupFileName);
+ SavedIncrementalBackup incrementalBackup = null;
+ if (backupFile.getName().endsWith(".kbi")) {
+ incrementalBackup = IncBackupInfoSerializer.fromFile(backupFile);
}
- try {
- if (!backupFile.delete())
- forceDelete(backupFile);
- } catch (SecurityException | NullPointerException | IOException ignored) {
+
+ // remove .zip or .kbi file
+ PrintUtil.info("Deleting file " + backupFileName + "...");
+ int tryCounter = 0;
+ do {
+ if (tryCounter == 5) {
+ String msg = "Failed to delete file " + backupFileName;
+ PrintUtil.error(msg);
+ msgErr(context, msg);
+ return;
+ }
+ try {
+ if (!backupFile.delete())
+ forceDelete(backupFile);
+ } catch (SecurityException | NullPointerException | IOException ignored) {
+ }
+ ++tryCounter;
+ } while (backupFile.exists());
+
+
+ // If it is an incremental backup, do clean-up
+ if (incrementalBackup != null) {
+ PrintUtil.info("Cleaning up...");
+ IncrementalBackupStorageManager manager =
+ new IncrementalBackupStorageManager(getIncrementalBackupBaseDirectory(server).toPath());
+ Iterable<ObjectCollection2> backups = ObjectCollectionSerializer
+ .fromDirectory(BackupFilesystemUtil
+ .getBackupSaveDirectory(context.getSource().getMinecraftServer()));
+ int deleted = manager.deleteObjectCollection(incrementalBackup.getObjectCollection(), backups);
+ PrintUtil.info("Deleted " + deleted + " unused file(s).");
}
- ++tryCounter;
- } while (backupFile.exists());
- PrintUtil.info("Successfully deleted backup file " + this.backupFileName);
- msgInfo(context, "Successfully deleted backup file " + this.backupFileName);
+
+ PrintUtil.info("Successfully deleted backup file " + this.backupFileName);
+ msgInfo(context, "Successfully deleted backup file " + this.backupFileName);
+ } catch (IOException e) {
+ LOGGER.severe("Failed to delete backup: " + e);
+ }
}
}
diff --git a/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java
index ffcc000..5cd58aa 100644
--- a/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java
+++ b/src/main/java/com/keuin/kbackupfabric/operation/backup/method/ConfiguredIncrementalBackupMethod.java
@@ -117,7 +117,7 @@ public class ConfiguredIncrementalBackupMethod implements ConfiguredBackupMethod
// so we perform a clean here
// perform a clean-up
Iterable<ObjectCollection2> backups = ObjectCollectionSerializer.fromDirectory(new File(backupIndexFileSaveDirectory));
- storageManager.deleteObjectCollection(collection, levelPathFile, backups);
+ storageManager.deleteObjectCollection(collection, backups);
} catch (IOException e) {
LOGGER.warning("An exception occurred while cleaning up: " + e);
}