diff --git a/src/main/java/net/horizoncode/sysbackup/tasks/TaskBuilder.java b/src/main/java/net/horizoncode/sysbackup/tasks/TaskBuilder.java index 380f9e8..fb7d157 100644 --- a/src/main/java/net/horizoncode/sysbackup/tasks/TaskBuilder.java +++ b/src/main/java/net/horizoncode/sysbackup/tasks/TaskBuilder.java @@ -3,11 +3,13 @@ package net.horizoncode.sysbackup.tasks; import lombok.Builder; import lombok.Getter; import net.horizoncode.sysbackup.config.Config; +import net.horizoncode.sysbackup.tasks.impl.DatabaseTask; import net.horizoncode.sysbackup.tasks.impl.FileSystemTask; import org.apache.commons.io.FilenameUtils; import org.tomlj.TomlArray; import java.io.File; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.LinkedBlockingQueue; @@ -34,7 +36,10 @@ public class TaskBuilder { new SimpleDateFormat( getTaskConfig().getStringOrDefault("general.dateFormat", "yyyy-MM-dd HH-mm-ss")); String fileName = - getTaskConfig().getStringOrDefault("filesystem.fileName", "{date} - {taskName}") + ".zip"; + getTaskConfig().getStringOrDefault("general.outputFile", "{date} - {taskName}") + ".zip"; + + boolean doFS = getTaskConfig().getBooleanOrDefault("filesystem.enabled", false); + boolean doDB = getTaskConfig().getBooleanOrDefault("mysql.enabled", false); fileName = fileName @@ -44,8 +49,7 @@ public class TaskBuilder { .replace("{date}", sdf.format(new Date())); File outputFile = new File(backupDir, fileName); - - if (getTaskConfig().getToml().contains("filesystem.targets")) { + if (doFS && getTaskConfig().getToml().contains("filesystem.targets")) { TomlArray filesArray = getTaskConfig().getArray("filesystem.targets"); IntStream.range(0, filesArray.size()) @@ -62,6 +66,31 @@ public class TaskBuilder { }); } + if (doDB) { + String database = getTaskConfig().getStringOrDefault("mysql.database", ""); + String user = getTaskConfig().getStringOrDefault("mysql.user", ""); + String password = getTaskConfig().getStringOrDefault("mysql.password", ""); + + if (!database.isEmpty() && !user.isEmpty() && !password.isEmpty()) { + DatabaseTask.DatabaseCredentials databaseCredentials = + DatabaseTask.DatabaseCredentials.builder() + .database(database) + .username(user) + .password(password.toCharArray()) + .build(); + + taskList.add( + new DatabaseTask(databaseCredentials, outputFile) { + @Override + public void onDone() { + executeNextTask(); + } + }); + } else { + System.err.println("username, password or database is empty."); + } + } + executeNextTask(); } @@ -70,7 +99,7 @@ public class TaskBuilder { if (nextTask != null) nextTask.start(); else { System.out.println("Backup completed!"); - System.out.println(0); + System.exit(0); } } } diff --git a/src/main/java/net/horizoncode/sysbackup/tasks/impl/DatabaseTask.java b/src/main/java/net/horizoncode/sysbackup/tasks/impl/DatabaseTask.java index 3ad59bf..3fe9542 100644 --- a/src/main/java/net/horizoncode/sysbackup/tasks/impl/DatabaseTask.java +++ b/src/main/java/net/horizoncode/sysbackup/tasks/impl/DatabaseTask.java @@ -2,17 +2,20 @@ package net.horizoncode.sysbackup.tasks.impl; import lombok.Builder; import lombok.Getter; +import me.tongfei.progressbar.ProgressBar; +import me.tongfei.progressbar.ProgressBarBuilder; +import me.tongfei.progressbar.ProgressBarStyle; import net.horizoncode.sysbackup.tasks.Task; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.progress.ProgressMonitor; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.stream.Collectors; @Getter public class DatabaseTask extends Task { @@ -29,24 +32,90 @@ public class DatabaseTask extends Task { @Override public void start() { try { - String[] commandArgs = - new String[] { - "mysqldump", - "-u " + getDatabaseCredentials().username, - "-p" + new String(getDatabaseCredentials().password), - getDatabaseCredentials().database - }; + String commandArgs = + "mysqldump -u " + + getDatabaseCredentials().username + + " -p" + + new String(getDatabaseCredentials().password) + + " " + + getDatabaseCredentials().database; + Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec(commandArgs); - InputStream inputStream = process.getInputStream(); - FileUtils.copyInputStreamToFile( - inputStream, + String databaseContent = ""; + + while (process.isAlive()) { + try { + Thread.sleep(1000); + databaseContent = + new BufferedReader( + new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + int exitValue = process.exitValue(); + + if (exitValue != 0) { + String text = + new BufferedReader( + new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8)) + .lines() + .collect(Collectors.joining("\n")); + System.out.println(text); + onDone(); + return; + } + + if (databaseContent.isEmpty()) { + System.err.println("database content is empty"); + onDone(); + return; + } + + File outputSQLFile = new File( outputFile.getParent(), String.format( "%s-%s.sql", - getDatabaseCredentials().database, RandomStringUtils.random(16, true, true)))); + getDatabaseCredentials().database, RandomStringUtils.random(16, true, true))); + + BufferedWriter writer = new BufferedWriter(new FileWriter(outputSQLFile)); + writer.write(databaseContent); + writer.close(); + System.out.println("Adding database to backup zip..."); + try (ZipFile zipFile = new ZipFile(getOutputFile())) { + ProgressMonitor progressMonitor = zipFile.getProgressMonitor(); + zipFile.setRunInThread(true); + zipFile.addFile(outputSQLFile); + ProgressBarBuilder pbb = + new ProgressBarBuilder() + .setStyle(ProgressBarStyle.ASCII) + .setInitialMax(progressMonitor.getTotalWork()) + .setTaskName("Adding DB File..."); + + try (ProgressBar pb = pbb.build()) { + while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) { + pb.stepTo(progressMonitor.getWorkCompleted()); + Thread.sleep(100); + } + pb.stepTo(progressMonitor.getTotalWork()); + } catch (Exception exception) { + exception.printStackTrace(); + FileUtils.deleteQuietly(outputSQLFile); + onDone(); + } + progressMonitor.endProgressMonitor(); + FileUtils.deleteQuietly(outputSQLFile); + onDone(); + } catch (Exception ex) { + ex.printStackTrace(); + onDone(); + } } catch (IOException e) { throw new RuntimeException(e); @@ -54,7 +123,7 @@ public class DatabaseTask extends Task { } @Builder - private static class DatabaseCredentials { + public static class DatabaseCredentials { private final String username; private final char[] password; private final String database;