mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-04-19 23:36:00 -04:00
Add rolling backup
This commit is contained in:
parent
530b15147c
commit
4c0cc738e4
@ -18,6 +18,7 @@
|
||||
package io.bitsquare.common.crypto;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.storage.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -86,6 +87,7 @@ public class KeyStorage {
|
||||
}
|
||||
|
||||
public KeyPair loadKeyPair(KeyEntry keyEntry) {
|
||||
FileUtil.rollingBackup(storageDir, keyEntry.getFileName() + ".key");
|
||||
// long now = System.currentTimeMillis();
|
||||
try {
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(keyEntry.getAlgorithm(), "BC");
|
||||
|
@ -303,17 +303,6 @@ public class Utilities {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void deleteDirectory(File file) throws IOException {
|
||||
if (file.isDirectory()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null)
|
||||
for (File c : files)
|
||||
deleteDirectory(c);
|
||||
}
|
||||
if (!file.delete())
|
||||
throw new FileNotFoundException("Failed to delete file: " + file);
|
||||
}
|
||||
|
||||
private static void printElapsedTime(String msg) {
|
||||
if (!msg.isEmpty()) {
|
||||
msg += " / ";
|
||||
@ -348,29 +337,6 @@ public class Utilities {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty and delete a folder (and subfolders).
|
||||
*
|
||||
* @param folder folder to empty
|
||||
*/
|
||||
private static void removeDirectory(final File folder) {
|
||||
// check if folder file is a real folder
|
||||
if (folder.isDirectory()) {
|
||||
File[] list = folder.listFiles();
|
||||
if (list != null) {
|
||||
for (File tmpF : list) {
|
||||
if (tmpF.isDirectory()) {
|
||||
removeDirectory(tmpF);
|
||||
}
|
||||
if (!tmpF.delete())
|
||||
log.warn("can't delete file : " + tmpF);
|
||||
}
|
||||
}
|
||||
if (!folder.delete())
|
||||
log.warn("can't delete folder : " + folder);
|
||||
}
|
||||
}
|
||||
|
||||
public static String readTextFileFromServer(String url, String userAgent) throws IOException {
|
||||
URLConnection connection = URI.create(url).toURL().openConnection();
|
||||
connection.setDoOutput(true);
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package io.bitsquare.storage;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import org.bitcoinj.core.Utils;
|
||||
@ -162,13 +161,7 @@ public class FileManager<T> {
|
||||
}
|
||||
|
||||
public synchronized void backupFile(String fileName) throws IOException {
|
||||
File backupDir = new File(Paths.get(dir.getAbsolutePath(), "backup").toString());
|
||||
if (!backupDir.exists())
|
||||
if (!backupDir.mkdir())
|
||||
log.warn("make dir failed");
|
||||
|
||||
File backupFile = new File(Paths.get(dir.getAbsolutePath(), "backup", fileName).toString());
|
||||
Files.copy(storageFile, backupFile);
|
||||
FileUtil.rollingBackup(dir, fileName);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
73
common/src/main/java/io/bitsquare/storage/FileUtil.java
Normal file
73
common/src/main/java/io/bitsquare/storage/FileUtil.java
Normal file
@ -0,0 +1,73 @@
|
||||
package io.bitsquare.storage;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class FileUtil {
|
||||
private static final Logger log = LoggerFactory.getLogger(FileUtil.class);
|
||||
|
||||
public static void rollingBackup(File dir, String fileName) {
|
||||
File backupDir = new File(Paths.get(dir.getAbsolutePath(), "backup").toString());
|
||||
if (!backupDir.exists())
|
||||
if (!backupDir.mkdir())
|
||||
log.warn("make dir failed");
|
||||
|
||||
File origFile = new File(Paths.get(dir.getAbsolutePath(), fileName).toString());
|
||||
if (origFile.exists()) {
|
||||
File backupFileDir = new File(Paths.get(backupDir.getAbsolutePath(), fileName.replace(".", "_")).toString());
|
||||
if (!backupFileDir.exists())
|
||||
if (!backupFileDir.mkdir())
|
||||
log.warn("make backupFileDir failed");
|
||||
|
||||
File backupFile = new File(Paths.get(backupFileDir.getAbsolutePath(), new Date().getTime() + "_" + fileName).toString());
|
||||
|
||||
try {
|
||||
Files.copy(origFile, backupFile);
|
||||
|
||||
pruneBackup(backupDir);
|
||||
} catch (IOException e) {
|
||||
log.error("Backup key failed " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void pruneBackup(File backupDir) {
|
||||
if (backupDir.isDirectory()) {
|
||||
File[] files = backupDir.listFiles();
|
||||
if (files != null) {
|
||||
List<File> filesList = Arrays.asList(files);
|
||||
if (filesList.size() > 10) {
|
||||
filesList.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
|
||||
File file = filesList.get(0);
|
||||
if (file.isFile()) {
|
||||
if (!file.delete())
|
||||
log.error("Failed to delete file: " + file);
|
||||
} else {
|
||||
pruneBackup(new File(Paths.get(backupDir.getAbsolutePath(), file.getName()).toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteDirectory(File file) throws IOException {
|
||||
if (file.isDirectory()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null)
|
||||
for (File c : files)
|
||||
deleteDirectory(c);
|
||||
}
|
||||
if (!file.delete())
|
||||
throw new FileNotFoundException("Failed to delete file: " + file);
|
||||
}
|
||||
}
|
@ -131,7 +131,6 @@ public class Storage<T extends Serializable> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void remove(String fileName) {
|
||||
fileManager.removeFile(fileName);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.bitsquare.common.crypto;
|
||||
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.storage.FileUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@ -37,7 +37,7 @@ public class EncryptionTest {
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
Utilities.deleteDirectory(dir);
|
||||
FileUtil.deleteDirectory(dir);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.bitsquare.common.crypto;
|
||||
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.storage.FileUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@ -35,7 +35,7 @@ public class SigTest {
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
Utilities.deleteDirectory(dir);
|
||||
FileUtil.deleteDirectory(dir);
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.ExceptionHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.storage.FileUtil;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.*;
|
||||
import org.bitcoinj.core.*;
|
||||
@ -48,8 +49,10 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -125,6 +128,9 @@ public class WalletService {
|
||||
exceptionHandler.handleException(new TimeoutException("Wallet did not initialize in " +
|
||||
STARTUP_TIMEOUT_SEC + " seconds.")), STARTUP_TIMEOUT_SEC);
|
||||
|
||||
|
||||
backupWallet();
|
||||
|
||||
// If seed is non-null it means we are restoring from backup.
|
||||
walletAppKit = new WalletAppKit(params, walletDir, "Bitsquare") {
|
||||
@Override
|
||||
@ -275,6 +281,19 @@ public class WalletService {
|
||||
}, "RestoreWallet-%d").start();
|
||||
}
|
||||
|
||||
public void backupWallet() {
|
||||
FileUtil.rollingBackup(walletDir, "Bitsquare.wallet");
|
||||
}
|
||||
|
||||
public void clearBackup() {
|
||||
try {
|
||||
FileUtil.deleteDirectory(new File(Paths.get(walletDir.getAbsolutePath(), "backup").toString()));
|
||||
} catch (IOException e) {
|
||||
log.error("Could not delete directory " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Listener
|
||||
@ -502,7 +521,7 @@ public class WalletService {
|
||||
public Coin getBalanceForAddressEntryWithTradeId(String tradeId) {
|
||||
return getBalanceForAddress(getTradeAddressEntry(tradeId).getAddress());
|
||||
}
|
||||
|
||||
|
||||
private Coin getBalance(List<TransactionOutput> transactionOutputs, Address address) {
|
||||
Coin balance = Coin.ZERO;
|
||||
for (TransactionOutput transactionOutput : transactionOutputs) {
|
||||
|
@ -118,6 +118,7 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
||||
.show();
|
||||
passwordField.setText("");
|
||||
repeatedPasswordField.setText("");
|
||||
walletService.backupWallet();
|
||||
} else {
|
||||
new Popup()
|
||||
.warning("You entered the wrong password.\n\n" +
|
||||
@ -133,6 +134,8 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
||||
.show();
|
||||
passwordField.setText("");
|
||||
repeatedPasswordField.setText("");
|
||||
walletService.clearBackup();
|
||||
walletService.backupWallet();
|
||||
}
|
||||
setText();
|
||||
});
|
||||
|
@ -20,10 +20,10 @@ package io.bitsquare.crypto;
|
||||
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.common.crypto.*;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.p2p.NodeAddress;
|
||||
import io.bitsquare.p2p.messaging.MailboxMessage;
|
||||
import io.bitsquare.p2p.messaging.PrefixedSealedAndSignedMessage;
|
||||
import io.bitsquare.storage.FileUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@ -66,7 +66,7 @@ public class EncryptionServiceTests {
|
||||
|
||||
@After
|
||||
public void tearDown() throws IOException {
|
||||
Utilities.deleteDirectory(dir);
|
||||
FileUtil.deleteDirectory(dir);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2,7 +2,6 @@ package io.bitsquare.p2p.storage;
|
||||
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.crypto.*;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.crypto.EncryptionService;
|
||||
import io.bitsquare.p2p.NodeAddress;
|
||||
import io.bitsquare.p2p.P2PService;
|
||||
@ -12,6 +11,7 @@ import io.bitsquare.p2p.peers.PeerManager;
|
||||
import io.bitsquare.p2p.storage.messages.RefreshTTLMessage;
|
||||
import io.bitsquare.p2p.storage.mocks.MockData;
|
||||
import io.bitsquare.p2p.storage.storageentry.ProtectedStorageEntry;
|
||||
import io.bitsquare.storage.FileUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.junit.*;
|
||||
import org.slf4j.Logger;
|
||||
@ -90,10 +90,9 @@ public class ProtectedDataStorageTest {
|
||||
|
||||
Path path = Paths.get(TestUtils.test_dummy_dir);
|
||||
File dir = path.toFile();
|
||||
Utilities.deleteDirectory(dir);
|
||||
|
||||
Utilities.deleteDirectory(dir1);
|
||||
Utilities.deleteDirectory(dir2);
|
||||
FileUtil.deleteDirectory(dir);
|
||||
FileUtil.deleteDirectory(dir1);
|
||||
FileUtil.deleteDirectory(dir2);
|
||||
}
|
||||
|
||||
//@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user