mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-09-20 19:00:58 +02:00
213 lines
7.4 KiB
Java
213 lines
7.4 KiB
Java
package fr.xephi.authme.service;
|
|
|
|
import fr.xephi.authme.ConsoleLogger;
|
|
import fr.xephi.authme.datasource.DataSourceType;
|
|
import fr.xephi.authme.initialization.DataFolder;
|
|
import fr.xephi.authme.output.ConsoleLoggerFactory;
|
|
import fr.xephi.authme.mail.EmailService;
|
|
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;
|
|
|
|
/**
|
|
* Performs a backup of the data source.
|
|
*/
|
|
public class BackupService {
|
|
|
|
private final ConsoleLogger logger = ConsoleLoggerFactory.get(EmailService.class);
|
|
|
|
private final File dataFolder;
|
|
private final File backupFolder;
|
|
private final Settings settings;
|
|
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param dataFolder the data folder
|
|
* @param settings the plugin settings
|
|
*/
|
|
@Inject
|
|
public BackupService(@DataFolder File dataFolder, Settings settings) {
|
|
this.dataFolder = dataFolder;
|
|
this.backupFolder = new File(dataFolder, "backups");
|
|
this.settings = settings;
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
logger.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()) {
|
|
logger.logAndSendMessage(sender,
|
|
"A backup has been performed successfully. Cause of the backup: " + cause.name());
|
|
} else {
|
|
logger.logAndSendWarning(sender, "Error while performing a backup! Cause of the backup: " + cause.name());
|
|
}
|
|
}
|
|
|
|
private boolean doBackup() {
|
|
DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND);
|
|
switch (dataSourceType) {
|
|
case MYSQL:
|
|
return performMySqlBackup();
|
|
case SQLITE:
|
|
String dbName = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
|
|
return performFileBackup(dbName + ".db");
|
|
default:
|
|
logger.warning("Unknown data source type '" + dataSourceType + "' for backup");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Performs a backup for the MySQL data source.
|
|
*
|
|
* @return true if successful, false otherwise
|
|
*/
|
|
private boolean performMySqlBackup() {
|
|
FileUtils.createDirectory(backupFolder);
|
|
File sqlBackupFile = constructBackupFile("sql");
|
|
|
|
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) {
|
|
logger.info("Backup created successfully. (Using Windows = " + isUsingWindows + ")");
|
|
return true;
|
|
} else {
|
|
logger.warning("Could not create the backup! (Using Windows = " + isUsingWindows + ")");
|
|
}
|
|
} catch (IOException | InterruptedException e) {
|
|
logger.logException("Error during backup (using Windows = " + isUsingWindows + "):", e);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private boolean performFileBackup(String filename) {
|
|
FileUtils.createDirectory(backupFolder);
|
|
File backupFile = constructBackupFile("db");
|
|
|
|
try {
|
|
copy(new File(dataFolder, filename), backupFile);
|
|
return true;
|
|
} catch (IOException ex) {
|
|
logger.logException("Encountered an error during file backup:", ex);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if we are under Windows and correct location of mysqldump.exe
|
|
* otherwise return error.
|
|
*
|
|
* @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 boolean useWindowsCommand(String windowsPath) {
|
|
String isWin = System.getProperty("os.name").toLowerCase();
|
|
if (isWin.contains("win")) {
|
|
if (new File(windowsPath + "\\bin\\mysqldump.exe").exists()) {
|
|
return true;
|
|
} else {
|
|
logger.warning("Mysql Windows Path is incorrect. Please check it");
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Possible backup causes.
|
|
*/
|
|
public enum BackupCause {
|
|
START,
|
|
STOP,
|
|
COMMAND,
|
|
OTHER
|
|
}
|
|
|
|
}
|