AuthMeReloaded/src/main/java/fr/xephi/authme/service/BackupService.java

208 lines
7.4 KiB
Java
Raw Normal View History

2016-10-04 19:08:18 +02:00
package fr.xephi.authme.service;
2013-03-09 03:42:17 +01:00
2016-10-04 19:08:18 +02:00
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.BackupSettings;
import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.util.FileUtils;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static fr.xephi.authme.util.Utils.logAndSendMessage;
import static fr.xephi.authme.util.Utils.logAndSendWarning;
2013-03-09 03:42:17 +01:00
/**
* Performs a backup of the data source.
2013-03-09 03:42:17 +01:00
*/
2016-10-04 19:08:18 +02:00
public class BackupService {
private final File dataFolder;
private final File backupFolder;
private final Settings settings;
2014-08-08 23:14:56 +02:00
2015-11-21 01:27:06 +01:00
/**
* Constructor.
*
* @param dataFolder the data folder
* @param settings the plugin settings
2015-11-21 01:27:06 +01:00
*/
@Inject
public BackupService(@DataFolder File dataFolder, Settings settings) {
this.dataFolder = dataFolder;
this.backupFolder = new File(dataFolder, "backups");
this.settings = settings;
2014-08-08 23:14:56 +02:00
}
/**
* Performs a backup for the given reason.
*
* @param cause backup reason
*/
public void doBackup(BackupCause cause) {
doBackup(cause, null);
}
/**
* Performs a backup for the given reason.
*
* @param cause backup reason
* @param sender the command sender (nullable)
*/
public void doBackup(BackupCause cause, CommandSender sender) {
if (!settings.getProperty(BackupSettings.ENABLED)) {
// Print a warning if the backup was requested via command or by another plugin
if (cause == BackupCause.COMMAND || cause == BackupCause.OTHER) {
logAndSendWarning(sender,
"Can't perform a backup: disabled in configuration. Cause of the backup: " + cause.name());
}
return;
} else if (BackupCause.START == cause && !settings.getProperty(BackupSettings.ON_SERVER_START)
|| BackupCause.STOP == cause && !settings.getProperty(BackupSettings.ON_SERVER_STOP)) {
// Don't perform backup on start or stop if so configured
return;
}
// Do backup and check return value!
if (doBackup()) {
logAndSendMessage(sender,
"A backup has been performed successfully. Cause of the backup: " + cause.name());
} else {
logAndSendWarning(sender, "Error while performing a backup! Cause of the backup: " + cause.name());
}
}
private boolean doBackup() {
DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND);
switch (dataSourceType) {
2014-08-08 23:14:56 +02:00
case FILE:
return performFileBackup("auths.db");
2014-08-08 23:14:56 +02:00
case MYSQL:
return performMySqlBackup();
2015-09-13 15:01:22 +02:00
case SQLITE:
String dbName = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
return performFileBackup(dbName + ".db");
default:
ConsoleLogger.warning("Unknown data source type '" + dataSourceType + "' for backup");
2014-08-08 23:14:56 +02:00
}
2013-03-09 03:42:17 +01:00
2014-08-08 23:14:56 +02:00
return false;
}
private boolean performMySqlBackup() {
FileUtils.createDirectory(backupFolder);
File sqlBackupFile = constructBackupFile("sql");
2014-08-08 23:14:56 +02:00
String backupWindowsPath = settings.getProperty(BackupSettings.MYSQL_WINDOWS_PATH);
boolean isUsingWindows = useWindowsCommand(backupWindowsPath);
String backupCommand = isUsingWindows
? backupWindowsPath + "\\bin\\mysqldump.exe" + buildMysqlDumpArguments(sqlBackupFile)
: "mysqldump" + buildMysqlDumpArguments(sqlBackupFile);
try {
Process runtimeProcess = Runtime.getRuntime().exec(backupCommand);
int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) {
ConsoleLogger.info("Backup created successfully. (Using Windows = " + isUsingWindows + ")");
return true;
} else {
ConsoleLogger.warning("Could not create the backup! (Using Windows = " + isUsingWindows + ")");
2014-08-08 23:14:56 +02:00
}
} catch (IOException | InterruptedException e) {
ConsoleLogger.logException("Error during backup (using Windows = " + isUsingWindows + "):", e);
2014-08-08 23:14:56 +02:00
}
return false;
}
private boolean performFileBackup(String filename) {
FileUtils.createDirectory(backupFolder);
File backupFile = constructBackupFile("db");
2013-03-09 03:42:17 +01:00
try {
copy(new File(dataFolder, filename), backupFile);
2014-08-08 23:14:56 +02:00
return true;
} catch (IOException ex) {
ConsoleLogger.logException("Encountered an error during file backup:", ex);
2013-03-09 03:42:17 +01:00
}
return false;
}
2015-11-21 01:27:06 +01:00
/**
* Check if we are under Windows and correct location of mysqldump.exe
* otherwise return error.
2015-11-23 21:46:34 +01:00
*
* @param windowsPath The path to check
* @return True if the path is correct, false if it is incorrect or the OS is not Windows
*/
private static boolean useWindowsCommand(String windowsPath) {
2014-08-08 23:14:56 +02:00
String isWin = System.getProperty("os.name").toLowerCase();
2015-11-23 21:43:40 +01:00
if (isWin.contains("win")) {
2014-08-08 23:14:56 +02:00
if (new File(windowsPath + "\\bin\\mysqldump.exe").exists()) {
return true;
} else {
ConsoleLogger.warning("Mysql Windows Path is incorrect. Please check it");
return false;
2014-08-08 23:14:56 +02:00
}
}
return false;
2013-03-09 03:42:17 +01:00
}
2014-08-08 23:14:56 +02:00
/**
* Builds the command line arguments to pass along when running the {@code mysqldump} command.
*
* @param sqlBackupFile the file to back up to
* @return the mysqldump command line arguments
*/
private String buildMysqlDumpArguments(File sqlBackupFile) {
String dbUsername = settings.getProperty(DatabaseSettings.MYSQL_USERNAME);
String dbPassword = settings.getProperty(DatabaseSettings.MYSQL_PASSWORD);
String dbName = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
String tableName = settings.getProperty(DatabaseSettings.MYSQL_TABLE);
return " -u " + dbUsername + " -p" + dbPassword + " " + dbName
+ " --tables " + tableName + " -r " + sqlBackupFile.getPath() + ".sql";
}
/**
* Constructs the file name to back up the data source to.
*
* @param fileExtension the file extension to use (e.g. sql)
* @return the file to back up the data to
*/
private File constructBackupFile(String fileExtension) {
String dateString = FileUtils.createCurrentTimeString();
return new File(backupFolder, "backup" + dateString + "." + fileExtension);
}
2014-08-08 23:14:56 +02:00
private static void copy(File src, File dst) throws IOException {
try (InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst)) {
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
2014-08-08 23:14:56 +02:00
}
2013-03-09 03:42:17 +01:00
}
2015-11-21 01:27:06 +01:00
/**
* Possible backup causes.
*/
public enum BackupCause {
START,
STOP,
COMMAND,
OTHER
2014-08-08 23:14:56 +02:00
}
2013-03-09 03:42:17 +01:00
}