Compare commits
	
		
			7 Commits
		
	
	
		
			724d303433
			...
			archived
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7142cd06dd | |||
| 8f9d7d5297 | |||
| e5abc4823d | |||
| c6eb4c8fdb | |||
| 626bb3e25a | |||
| 2eddf3cc2a | |||
| ad208f9580 | 
							
								
								
									
										5
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -59,6 +59,11 @@ | |||||||
|       <artifactId>commons-lang3</artifactId> |       <artifactId>commons-lang3</artifactId> | ||||||
|       <version>3.12.0</version> |       <version>3.12.0</version> | ||||||
|     </dependency> |     </dependency> | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>com.diogonunes</groupId> | ||||||
|  |       <artifactId>JColor</artifactId> | ||||||
|  |       <version>5.5.1</version> | ||||||
|  |     </dependency> | ||||||
|     <!-- testing dependencies --> |     <!-- testing dependencies --> | ||||||
|     <dependency> |     <dependency> | ||||||
|       <groupId>junit</groupId> |       <groupId>junit</groupId> | ||||||
|   | |||||||
| @@ -1,18 +1,10 @@ | |||||||
| import net.horizoncode.sysbackup.cli.CLIProcessor; | import net.horizoncode.sysbackup.SysBackup; | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.net.URISyntaxException; | import java.net.URISyntaxException; | ||||||
|  |  | ||||||
| public class Bootstrapper { | public class Bootstrapper { | ||||||
|  |  | ||||||
|   public static void main(String[] args) throws URISyntaxException { |   public static void main(String[] args) throws URISyntaxException { | ||||||
|  |     new SysBackup().start(args); | ||||||
|     File executionPath = |  | ||||||
|         new File( |  | ||||||
|             new File(Bootstrapper.class.getProtectionDomain().getCodeSource().getLocation().toURI()) |  | ||||||
|                 .getParent()); |  | ||||||
|  |  | ||||||
|     CLIProcessor cliProcessor = new CLIProcessor(); |  | ||||||
|     cliProcessor.startCLI(args, executionPath); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								src/main/java/net/horizoncode/sysbackup/SysBackup.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/main/java/net/horizoncode/sysbackup/SysBackup.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | package net.horizoncode.sysbackup; | ||||||
|  |  | ||||||
|  | import lombok.Getter; | ||||||
|  | import net.horizoncode.sysbackup.cli.CLIProcessor; | ||||||
|  | import net.horizoncode.sysbackup.logging.Logger; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  | import java.net.URISyntaxException; | ||||||
|  |  | ||||||
|  | public class SysBackup { | ||||||
|  |  | ||||||
|  |   @Getter private static final Logger logger = Logger.builder().logFile(new File("log")).build(); | ||||||
|  |  | ||||||
|  |   public void start(String[] args) throws URISyntaxException { | ||||||
|  |     File jarFile = | ||||||
|  |         new File(SysBackup.class.getProtectionDomain().getCodeSource().getLocation().toURI()); | ||||||
|  |  | ||||||
|  |     File executionPath = | ||||||
|  |         new File( | ||||||
|  |             new File(SysBackup.class.getProtectionDomain().getCodeSource().getLocation().toURI()) | ||||||
|  |                 .getParent()); | ||||||
|  |  | ||||||
|  |     if (!jarFile.isFile()) getLogger().log(Logger.LogLevel.INFO, "Dev environment detected!"); | ||||||
|  |  | ||||||
|  |     CLIProcessor cliProcessor = new CLIProcessor(); | ||||||
|  |     cliProcessor.startCLI( | ||||||
|  |         args, jarFile.isFile() ? executionPath : new File(System.getProperty("user.dir"))); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -1,13 +1,17 @@ | |||||||
| package net.horizoncode.sysbackup.cli; | package net.horizoncode.sysbackup.cli; | ||||||
|  |  | ||||||
|  | import net.horizoncode.sysbackup.SysBackup; | ||||||
| import net.horizoncode.sysbackup.config.Config; | import net.horizoncode.sysbackup.config.Config; | ||||||
|  | import net.horizoncode.sysbackup.logging.Logger; | ||||||
| import net.horizoncode.sysbackup.tasks.TaskBuilder; | import net.horizoncode.sysbackup.tasks.TaskBuilder; | ||||||
| import org.apache.commons.io.FileUtils; | import org.apache.commons.io.FileUtils; | ||||||
|  | import org.apache.commons.io.FilenameUtils; | ||||||
| import org.tomlj.Toml; | import org.tomlj.Toml; | ||||||
| import org.tomlj.TomlParseResult; | import org.tomlj.TomlParseResult; | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.Objects; | import java.util.Objects; | ||||||
|  |  | ||||||
| @@ -25,9 +29,7 @@ public class CLIProcessor { | |||||||
|       "    java -jar sysbackup.jar generateTaskConf magento", |       "    java -jar sysbackup.jar generateTaskConf magento", | ||||||
|       "    java -jar sysbackup.jar backup magento" |       "    java -jar sysbackup.jar backup magento" | ||||||
|     }; |     }; | ||||||
|     for (String u : usage) { |     Arrays.stream(usage).forEach(System.out::println); | ||||||
|       System.out.println(u); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public void startCLI(String[] args, File executionPath) { |   public void startCLI(String[] args, File executionPath) { | ||||||
| @@ -37,75 +39,92 @@ public class CLIProcessor { | |||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       Logger logger = SysBackup.getLogger(); | ||||||
|  |  | ||||||
|       for (int index = 0; index < args.length; index++) { |       for (int index = 0; index < args.length; index++) { | ||||||
|         switch (args[index].toLowerCase(Locale.ROOT)) { |         switch (args[index].toLowerCase(Locale.ROOT)) { | ||||||
|           case "backup": |           case "backup": | ||||||
|             { |             { | ||||||
|               if (args.length <= 1) { |               if (args.length <= 1) { | ||||||
|                 System.err.println("Please specify a output task config name!"); |                 logger.log(Logger.LogLevel.WARN, "Please specify a output task config name!"); | ||||||
|                 return; |                 return; | ||||||
|               } |               } | ||||||
|               String fileName = args[1]; |               String fileName = args[1]; | ||||||
|               File tasksFolder = new File(executionPath, "tasks"); |               File tasksFolder = new File(executionPath, "tasks"); | ||||||
|               if (!tasksFolder.exists()) |               if (!tasksFolder.exists()) | ||||||
|                 if (!tasksFolder.mkdir()) System.err.println("Failed to create tasks folder!"); |                 if (!tasksFolder.mkdir()) | ||||||
|  |                   logger.log(Logger.LogLevel.ERROR, "Failed to create tasks folder!"); | ||||||
|               File taskFile = new File(tasksFolder, fileName + ".toml"); |               File taskFile = new File(tasksFolder, fileName + ".toml"); | ||||||
|               if (!taskFile.exists()) { |               if (!taskFile.exists()) { | ||||||
|                 System.err.println("TaskFile " + fileName + ".toml does not exist!"); |                 logger.log(Logger.LogLevel.ERROR, "TaskFile %s.toml does not exist!", fileName); | ||||||
|                 return; |                 return; | ||||||
|               } |               } | ||||||
|  |  | ||||||
|  |               logger.log(Logger.LogLevel.INFO, "setupping TaskBuilder..."); | ||||||
|               Config taskConfig = new Config(taskFile); |               Config taskConfig = new Config(taskFile); | ||||||
|               TaskBuilder taskBuilder = |               TaskBuilder taskBuilder = | ||||||
|                   TaskBuilder.builder().executionPath(executionPath).taskConfig(taskConfig).build(); |                   TaskBuilder.builder() | ||||||
|  |                       .executionPath(executionPath) | ||||||
|  |                       .taskName(FilenameUtils.removeExtension(taskFile.getName())) | ||||||
|  |                       .taskConfig(taskConfig) | ||||||
|  |                       .build(); | ||||||
|               taskBuilder.start(); |               taskBuilder.start(); | ||||||
|               break; |               break; | ||||||
|             } |             } | ||||||
|           case "generatetaskconf": |           case "generatetaskconf": | ||||||
|             { |             { | ||||||
|               if (args.length <= 1) { |               if (args.length <= 1) { | ||||||
|                 System.err.println("Please specify a output task config name!"); |                 logger.log(Logger.LogLevel.ERROR, "Please specify a output task config name!"); | ||||||
|                 return; |                 return; | ||||||
|               } |               } | ||||||
|               String fileName = args[1]; |               String fileName = args[1]; | ||||||
|               File tasksFolder = new File(executionPath, "tasks"); |               File tasksFolder = new File(executionPath, "tasks"); | ||||||
|               if (!tasksFolder.exists()) |               if (!tasksFolder.exists()) | ||||||
|                 if (!tasksFolder.mkdir()) System.err.println("Failed to create tasks folder!"); |                 if (!tasksFolder.mkdir()) | ||||||
|               System.out.println("Saving task config " + fileName + ".toml..."); |                   logger.log(Logger.LogLevel.ERROR, "Failed to create tasks folder!"); | ||||||
|               FileUtils.copyInputStreamToFile( |               logger.log(Logger.LogLevel.INFO, "Saving task config %s.toml...", fileName); | ||||||
|                   Objects.requireNonNull(getClass().getResourceAsStream("/" + "exampletask.toml")), |               try { | ||||||
|                   new File(tasksFolder, fileName + ".toml")); |                 FileUtils.copyInputStreamToFile( | ||||||
|               System.out.println(fileName + ".toml saved!"); |                     Objects.requireNonNull( | ||||||
|  |                         getClass().getResourceAsStream("/" + "exampletask.toml")), | ||||||
|  |                     new File(tasksFolder, fileName + ".toml")); | ||||||
|  |               } catch (IOException exception) { | ||||||
|  |                 logger.log(Logger.LogLevel.ERROR, "Failed to save task config."); | ||||||
|  |               } | ||||||
|  |               logger.log(Logger.LogLevel.INFO, "%s.toml saved!", fileName); | ||||||
|               break; |               break; | ||||||
|             } |             } | ||||||
|           case "checktaskconf": |           case "checktaskconf": | ||||||
|             { |             { | ||||||
|               if (args.length <= 1) { |               if (args.length <= 1) { | ||||||
|                 System.err.println("Please specify a output task config name!"); |                 logger.log(Logger.LogLevel.ERROR, "Please specify a output task config name!"); | ||||||
|                 return; |                 return; | ||||||
|               } |               } | ||||||
|               String fileName = args[1]; |               String fileName = args[1]; | ||||||
|               File tasksFolder = new File(executionPath, "tasks"); |               File tasksFolder = new File(executionPath, "tasks"); | ||||||
|               if (!tasksFolder.exists()) |               if (!tasksFolder.exists()) | ||||||
|                 if (!tasksFolder.mkdir()) System.err.println("Failed to create tasks folder!"); |                 if (!tasksFolder.mkdir()) | ||||||
|  |                   logger.log(Logger.LogLevel.ERROR, "Failed to create tasks folder!"); | ||||||
|               File taskFile = new File(tasksFolder, fileName + ".toml"); |               File taskFile = new File(tasksFolder, fileName + ".toml"); | ||||||
|               if (!taskFile.exists()) { |               if (!taskFile.exists()) { | ||||||
|                 System.err.println("TaskFile " + fileName + ".toml does not exist!"); |                 logger.log(Logger.LogLevel.ERROR, "TaskFile %s.toml does not exist!", fileName); | ||||||
|                 return; |                 return; | ||||||
|               } |               } | ||||||
|               TomlParseResult toml; |               TomlParseResult toml; | ||||||
|               try { |               try { | ||||||
|                 toml = Toml.parse(taskFile.toPath()); |                 toml = Toml.parse(taskFile.toPath()); | ||||||
|               } catch (IOException e) { |               } catch (IOException e) { | ||||||
|                 System.err.println("failed to read TaskFile."); |                 logger.log(Logger.LogLevel.ERROR, "failed to read TaskFile."); | ||||||
|                 throw new RuntimeException(e); |                 throw new RuntimeException(e); | ||||||
|               } |               } | ||||||
|               if (toml.hasErrors()) { |               if (toml.hasErrors()) { | ||||||
|                 System.err.printf( |                 logger.log( | ||||||
|                     "TaskFile checked: found %d issues!:\n", (long) toml.errors().size()); |                     Logger.LogLevel.ERROR, | ||||||
|                 toml.errors().forEach(error -> System.err.println(error.toString())); |                     "TaskFile checked: found %d issues!:\n", | ||||||
|  |                     (long) toml.errors().size()); | ||||||
|  |                 toml.errors().forEach(error -> logger.log(Logger.LogLevel.ERROR, error.toString())); | ||||||
|               } else { |               } else { | ||||||
|                 System.out.println("TaskFile checked successfully: no issues found!"); |                 logger.log(Logger.LogLevel.INFO, "TaskFile checked successfully: no issues found!"); | ||||||
|               } |               } | ||||||
|               break; |               break; | ||||||
|             } |             } | ||||||
| @@ -117,6 +136,7 @@ public class CLIProcessor { | |||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } catch (Throwable t) { |     } catch (Throwable t) { | ||||||
|  |       SysBackup.getLogger().log(Logger.LogLevel.ERROR, t.getMessage()); | ||||||
|       t.printStackTrace(); |       t.printStackTrace(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										48
									
								
								src/main/java/net/horizoncode/sysbackup/logging/Logger.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/main/java/net/horizoncode/sysbackup/logging/Logger.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | package net.horizoncode.sysbackup.logging; | ||||||
|  |  | ||||||
|  | import com.diogonunes.jcolor.Ansi; | ||||||
|  | import com.diogonunes.jcolor.Attribute; | ||||||
|  | import lombok.Builder; | ||||||
|  | import lombok.Getter; | ||||||
|  | import org.apache.commons.io.FileUtils; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  | import java.io.IOException; | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | import java.util.Date; | ||||||
|  |  | ||||||
|  | @Builder | ||||||
|  | public class Logger { | ||||||
|  |   private File logFile; | ||||||
|  |  | ||||||
|  |   public void log(LogLevel logLevel, String message, Object... args) { | ||||||
|  |     SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); | ||||||
|  |     String prefix = | ||||||
|  |         String.format( | ||||||
|  |             "[%s - %s] ", | ||||||
|  |             sdf.format(new Date()), Ansi.colorize(logLevel.name(), logLevel.getColor())); | ||||||
|  |     String line = prefix + message; | ||||||
|  |     System.out.printf(line + "\r\n", args); | ||||||
|  |  | ||||||
|  |     // append to logfile | ||||||
|  |     try { | ||||||
|  |       FileUtils.writeStringToFile( | ||||||
|  |           logFile, line.replaceAll("\u001B\\[[;\\d]*m", "") + "\r\n", StandardCharsets.UTF_8, true); | ||||||
|  |     } catch (IOException ex) { | ||||||
|  |       ex.printStackTrace(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public enum LogLevel { | ||||||
|  |     INFO(Attribute.CYAN_TEXT()), | ||||||
|  |     WARN(Attribute.YELLOW_TEXT()), | ||||||
|  |     ERROR(Attribute.RED_TEXT()); | ||||||
|  |  | ||||||
|  |     @Getter private final Attribute color; | ||||||
|  |  | ||||||
|  |     LogLevel(Attribute color) { | ||||||
|  |       this.color = color; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -2,14 +2,19 @@ package net.horizoncode.sysbackup.tasks; | |||||||
|  |  | ||||||
| import lombok.Builder; | import lombok.Builder; | ||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
|  | import net.horizoncode.sysbackup.SysBackup; | ||||||
| import net.horizoncode.sysbackup.config.Config; | import net.horizoncode.sysbackup.config.Config; | ||||||
|  | import net.horizoncode.sysbackup.logging.Logger; | ||||||
| import net.horizoncode.sysbackup.tasks.impl.DatabaseTask; | import net.horizoncode.sysbackup.tasks.impl.DatabaseTask; | ||||||
| import net.horizoncode.sysbackup.tasks.impl.FileSystemTask; | import net.horizoncode.sysbackup.tasks.impl.FileSystemTask; | ||||||
|  | import net.horizoncode.sysbackup.tasks.impl.VacuumTask; | ||||||
|  | import net.horizoncode.sysbackup.threading.ThreadPool; | ||||||
| import org.apache.commons.io.FilenameUtils; | import org.apache.commons.io.FilenameUtils; | ||||||
| import org.tomlj.TomlArray; | import org.tomlj.TomlArray; | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||||
|  | import java.time.temporal.ChronoUnit; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
| import java.util.concurrent.LinkedBlockingQueue; | import java.util.concurrent.LinkedBlockingQueue; | ||||||
| import java.util.stream.IntStream; | import java.util.stream.IntStream; | ||||||
| @@ -20,16 +25,28 @@ public class TaskBuilder { | |||||||
|  |  | ||||||
|   private final Config taskConfig; |   private final Config taskConfig; | ||||||
|  |  | ||||||
|  |   private final String taskName; | ||||||
|  |  | ||||||
|   @Builder.Default private final LinkedBlockingQueue<Task> taskList = new LinkedBlockingQueue<>(); |   @Builder.Default private final LinkedBlockingQueue<Task> taskList = new LinkedBlockingQueue<>(); | ||||||
|  |   @Builder.Default @Getter private final ThreadPool threadPool = new ThreadPool(3, 10); | ||||||
|  |  | ||||||
|   private final File executionPath; |   private final File executionPath; | ||||||
|  |  | ||||||
|   public void start() { |   public void start() { | ||||||
|  |  | ||||||
|     File backupDir = new File(executionPath, "backups"); |     Logger logger = SysBackup.getLogger(); | ||||||
|  |  | ||||||
|  |     File rootBackupDir = new File(executionPath, "backups"); | ||||||
|  |     if (!rootBackupDir.exists()) | ||||||
|  |       if (!rootBackupDir.mkdir()) { | ||||||
|  |         logger.log(Logger.LogLevel.ERROR, "Failed to create root backup directory!"); | ||||||
|  |         System.exit(2); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     File backupDir = new File(rootBackupDir, getTaskName()); | ||||||
|     if (!backupDir.exists()) |     if (!backupDir.exists()) | ||||||
|       if (!backupDir.mkdir()) { |       if (!backupDir.mkdir()) { | ||||||
|         System.err.println("Failed to create backups directory!"); |         logger.log(Logger.LogLevel.ERROR, "Failed to create backup directory!"); | ||||||
|         System.exit(2); |         System.exit(2); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -38,7 +55,7 @@ public class TaskBuilder { | |||||||
|             getTaskConfig().getStringOrDefault("general.dateFormat", "yyyy-MM-dd HH-mm-ss")); |             getTaskConfig().getStringOrDefault("general.dateFormat", "yyyy-MM-dd HH-mm-ss")); | ||||||
|     String fileName = |     String fileName = | ||||||
|         getTaskConfig().getStringOrDefault("general.outputFile", "{date} - {taskName}") + ".zip"; |         getTaskConfig().getStringOrDefault("general.outputFile", "{date} - {taskName}") + ".zip"; | ||||||
|  |     boolean doVAC = getTaskConfig().getBooleanOrDefault("vacuum.enabled", false); | ||||||
|     boolean doFS = getTaskConfig().getBooleanOrDefault("filesystem.enabled", false); |     boolean doFS = getTaskConfig().getBooleanOrDefault("filesystem.enabled", false); | ||||||
|     boolean doDB = getTaskConfig().getBooleanOrDefault("mysql.enabled", false); |     boolean doDB = getTaskConfig().getBooleanOrDefault("mysql.enabled", false); | ||||||
|  |  | ||||||
| @@ -50,18 +67,39 @@ public class TaskBuilder { | |||||||
|             .replace("{date}", sdf.format(new Date())); |             .replace("{date}", sdf.format(new Date())); | ||||||
|  |  | ||||||
|     File outputFile = new File(backupDir, fileName); |     File outputFile = new File(backupDir, fileName); | ||||||
|  |  | ||||||
|  |     if (doVAC) { | ||||||
|  |       ChronoUnit unit = | ||||||
|  |           ChronoUnit.valueOf( | ||||||
|  |               getTaskConfig().getStringOrDefault("vacuum.unit", ChronoUnit.DAYS.name())); | ||||||
|  |  | ||||||
|  |       int value = getTaskConfig().getIntOrDefault("vacuum.time", 5); | ||||||
|  |  | ||||||
|  |       logger.log( | ||||||
|  |           Logger.LogLevel.INFO, "Adding VacuumTask with lifetime of %d %s%n", value, unit.name()); | ||||||
|  |       taskList.add( | ||||||
|  |           new VacuumTask(backupDir, unit, value) { | ||||||
|  |             @Override | ||||||
|  |             public void onDone() { | ||||||
|  |               getThreadPool().getPool().submit(() -> executeNextTask()); | ||||||
|  |             } | ||||||
|  |           }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (doFS && getTaskConfig().getToml().contains("filesystem.targets")) { |     if (doFS && getTaskConfig().getToml().contains("filesystem.targets")) { | ||||||
|  |       logger.log(Logger.LogLevel.INFO, "Adding FileSystemTask..."); | ||||||
|       TomlArray filesArray = getTaskConfig().getArray("filesystem.targets"); |       TomlArray filesArray = getTaskConfig().getArray("filesystem.targets"); | ||||||
|  |  | ||||||
|       IntStream.range(0, filesArray.size()) |       IntStream.range(0, filesArray.size()) | ||||||
|           .forEach( |           .forEach( | ||||||
|               value -> { |               value -> { | ||||||
|                 String target = filesArray.getString(value); |                 String target = filesArray.getString(value); | ||||||
|  |                 logger.log(Logger.LogLevel.INFO, "Adding \"%s\"", target); | ||||||
|                 taskList.add( |                 taskList.add( | ||||||
|                     new FileSystemTask(target, outputFile) { |                     new FileSystemTask(target, outputFile) { | ||||||
|                       @Override |                       @Override | ||||||
|                       public void onDone() { |                       public void onDone() { | ||||||
|                         executeNextTask(); |                         getThreadPool().getPool().submit(() -> executeNextTask()); | ||||||
|                       } |                       } | ||||||
|                     }); |                     }); | ||||||
|               }); |               }); | ||||||
| @@ -80,26 +118,28 @@ public class TaskBuilder { | |||||||
|                 .password(password.toCharArray()) |                 .password(password.toCharArray()) | ||||||
|                 .build(); |                 .build(); | ||||||
|  |  | ||||||
|  |         logger.log(Logger.LogLevel.INFO, "Adding DatabaseTask for database \"%s\"", database); | ||||||
|  |  | ||||||
|         taskList.add( |         taskList.add( | ||||||
|             new DatabaseTask(databaseCredentials, outputFile) { |             new DatabaseTask(databaseCredentials, outputFile) { | ||||||
|               @Override |               @Override | ||||||
|               public void onDone() { |               public void onDone() { | ||||||
|                 executeNextTask(); |                 getThreadPool().getPool().submit(() -> executeNextTask()); | ||||||
|               } |               } | ||||||
|             }); |             }); | ||||||
|       } else { |       } else { | ||||||
|         System.err.println("username, password or database is empty."); |         logger.log(Logger.LogLevel.ERROR, "username, password or database is empty."); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     executeNextTask(); |     getThreadPool().getPool().submit(this::executeNextTask); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private void executeNextTask() { |   private void executeNextTask() { | ||||||
|     Task nextTask = taskList.poll(); |     Task nextTask = taskList.poll(); | ||||||
|     if (nextTask != null) nextTask.start(); |     if (nextTask != null) nextTask.start(); | ||||||
|     else { |     else { | ||||||
|       System.out.println("Backup completed!"); |       SysBackup.getLogger().log(Logger.LogLevel.INFO, "Backup completed!"); | ||||||
|       System.exit(0); |       System.exit(0); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -5,6 +5,8 @@ import lombok.Getter; | |||||||
| import me.tongfei.progressbar.ProgressBar; | import me.tongfei.progressbar.ProgressBar; | ||||||
| import me.tongfei.progressbar.ProgressBarBuilder; | import me.tongfei.progressbar.ProgressBarBuilder; | ||||||
| import me.tongfei.progressbar.ProgressBarStyle; | import me.tongfei.progressbar.ProgressBarStyle; | ||||||
|  | import net.horizoncode.sysbackup.SysBackup; | ||||||
|  | import net.horizoncode.sysbackup.logging.Logger; | ||||||
| import net.horizoncode.sysbackup.tasks.Task; | import net.horizoncode.sysbackup.tasks.Task; | ||||||
| import net.lingala.zip4j.ZipFile; | import net.lingala.zip4j.ZipFile; | ||||||
| import net.lingala.zip4j.progress.ProgressMonitor; | import net.lingala.zip4j.progress.ProgressMonitor; | ||||||
| @@ -29,6 +31,7 @@ public class DatabaseTask extends Task { | |||||||
|   @Override |   @Override | ||||||
|   public void start() { |   public void start() { | ||||||
|     try { |     try { | ||||||
|  |       Logger logger = SysBackup.getLogger(); | ||||||
|       String commandArgs = |       String commandArgs = | ||||||
|           "mysqldump -u " |           "mysqldump -u " | ||||||
|               + getDatabaseCredentials().username |               + getDatabaseCredentials().username | ||||||
| @@ -51,6 +54,7 @@ public class DatabaseTask extends Task { | |||||||
|                   .lines() |                   .lines() | ||||||
|                   .collect(Collectors.joining("\n")); |                   .collect(Collectors.joining("\n")); | ||||||
|         } catch (InterruptedException e) { |         } catch (InterruptedException e) { | ||||||
|  |           logger.log(Logger.LogLevel.ERROR, e.getMessage()); | ||||||
|           throw new RuntimeException(e); |           throw new RuntimeException(e); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
| @@ -63,13 +67,13 @@ public class DatabaseTask extends Task { | |||||||
|                     new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8)) |                     new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8)) | ||||||
|                 .lines() |                 .lines() | ||||||
|                 .collect(Collectors.joining("\n")); |                 .collect(Collectors.joining("\n")); | ||||||
|         System.out.println(text); |         logger.log(Logger.LogLevel.ERROR, text); | ||||||
|         onDone(); |         onDone(); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (databaseContent.isEmpty()) { |       if (databaseContent.isEmpty()) { | ||||||
|         System.err.println("database content is empty"); |         logger.log(Logger.LogLevel.ERROR, "database content is empty"); | ||||||
|         onDone(); |         onDone(); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
| @@ -84,7 +88,7 @@ public class DatabaseTask extends Task { | |||||||
|       BufferedWriter writer = new BufferedWriter(new FileWriter(outputSQLFile)); |       BufferedWriter writer = new BufferedWriter(new FileWriter(outputSQLFile)); | ||||||
|       writer.write(databaseContent); |       writer.write(databaseContent); | ||||||
|       writer.close(); |       writer.close(); | ||||||
|       System.out.println("Adding database to backup zip..."); |       logger.log(Logger.LogLevel.INFO, "Adding database to backup zip..."); | ||||||
|       try (ZipFile zipFile = new ZipFile(getOutputFile())) { |       try (ZipFile zipFile = new ZipFile(getOutputFile())) { | ||||||
|         ProgressMonitor progressMonitor = zipFile.getProgressMonitor(); |         ProgressMonitor progressMonitor = zipFile.getProgressMonitor(); | ||||||
|         zipFile.setRunInThread(true); |         zipFile.setRunInThread(true); | ||||||
| @@ -103,6 +107,7 @@ public class DatabaseTask extends Task { | |||||||
|           } |           } | ||||||
|           pb.stepTo(progressMonitor.getTotalWork()); |           pb.stepTo(progressMonitor.getTotalWork()); | ||||||
|         } catch (Exception exception) { |         } catch (Exception exception) { | ||||||
|  |           logger.log(Logger.LogLevel.ERROR, exception.getMessage()); | ||||||
|           exception.printStackTrace(); |           exception.printStackTrace(); | ||||||
|           outputSQLFile.deleteOnExit(); |           outputSQLFile.deleteOnExit(); | ||||||
|           onDone(); |           onDone(); | ||||||
| @@ -111,11 +116,13 @@ public class DatabaseTask extends Task { | |||||||
|         outputSQLFile.deleteOnExit(); |         outputSQLFile.deleteOnExit(); | ||||||
|         onDone(); |         onDone(); | ||||||
|       } catch (Exception ex) { |       } catch (Exception ex) { | ||||||
|  |         logger.log(Logger.LogLevel.ERROR, ex.getMessage()); | ||||||
|         ex.printStackTrace(); |         ex.printStackTrace(); | ||||||
|         onDone(); |         onDone(); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     } catch (IOException e) { |     } catch (IOException e) { | ||||||
|  |       SysBackup.getLogger().log(Logger.LogLevel.ERROR, e.getMessage()); | ||||||
|       throw new RuntimeException(e); |       throw new RuntimeException(e); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -3,8 +3,9 @@ package net.horizoncode.sysbackup.tasks.impl; | |||||||
| import me.tongfei.progressbar.ProgressBar; | import me.tongfei.progressbar.ProgressBar; | ||||||
| import me.tongfei.progressbar.ProgressBarBuilder; | import me.tongfei.progressbar.ProgressBarBuilder; | ||||||
| import me.tongfei.progressbar.ProgressBarStyle; | import me.tongfei.progressbar.ProgressBarStyle; | ||||||
|  | import net.horizoncode.sysbackup.SysBackup; | ||||||
|  | import net.horizoncode.sysbackup.logging.Logger; | ||||||
| import net.horizoncode.sysbackup.tasks.Task; | import net.horizoncode.sysbackup.tasks.Task; | ||||||
| import net.horizoncode.sysbackup.threading.ThreadPool; |  | ||||||
| import net.lingala.zip4j.ZipFile; | import net.lingala.zip4j.ZipFile; | ||||||
| import net.lingala.zip4j.progress.ProgressMonitor; | import net.lingala.zip4j.progress.ProgressMonitor; | ||||||
|  |  | ||||||
| @@ -16,14 +17,13 @@ public class FileSystemTask extends Task { | |||||||
|   private final File target; |   private final File target; | ||||||
|   private File outputZipFile; |   private File outputZipFile; | ||||||
|  |  | ||||||
|   private final ThreadPool threadPool; |  | ||||||
|  |  | ||||||
|   public FileSystemTask(String folderOrFilePath, File outputZipFile) { |   public FileSystemTask(String folderOrFilePath, File outputZipFile) { | ||||||
|     this.threadPool = new ThreadPool(3, 10); |  | ||||||
|     this.target = Paths.get(folderOrFilePath).toFile(); |     this.target = Paths.get(folderOrFilePath).toFile(); | ||||||
|  |     Logger logger = SysBackup.getLogger(); | ||||||
|     if (!target.exists()) { |     if (!target.exists()) { | ||||||
|       onDone(); |       onDone(); | ||||||
|       System.err.println("File or folder named \"" + folderOrFilePath + "\" does not exist."); |       logger.log( | ||||||
|  |           Logger.LogLevel.ERROR, "File or folder named \"%s\" does not exist.", folderOrFilePath); | ||||||
|       System.exit(2); |       System.exit(2); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| @@ -33,38 +33,36 @@ public class FileSystemTask extends Task { | |||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public void start() { |   public void start() { | ||||||
|     threadPool |     Logger logger = SysBackup.getLogger(); | ||||||
|         .getPool() |     try (ZipFile zipFile = new ZipFile(outputZipFile)) { | ||||||
|         .submit( |       logger.log(Logger.LogLevel.INFO, "Indexing files..."); | ||||||
|             () -> { |       ProgressMonitor progressMonitor = zipFile.getProgressMonitor(); | ||||||
|               try (ZipFile zipFile = new ZipFile(outputZipFile)) { |       zipFile.setRunInThread(true); | ||||||
|                 System.out.println("Indexing files..."); |       zipFile.addFolder(target); | ||||||
|                 ProgressMonitor progressMonitor = zipFile.getProgressMonitor(); |       ProgressBarBuilder pbb = | ||||||
|                 zipFile.setRunInThread(true); |           new ProgressBarBuilder() | ||||||
|                 zipFile.addFolder(target); |               .setStyle(ProgressBarStyle.ASCII) | ||||||
|                 ProgressBarBuilder pbb = |               .setInitialMax(progressMonitor.getTotalWork()) | ||||||
|                     new ProgressBarBuilder() |               .setTaskName("Adding Files...") | ||||||
|                         .setStyle(ProgressBarStyle.ASCII) |               .setUnit("MiB", 1048576); | ||||||
|                         .setInitialMax(progressMonitor.getTotalWork()) |  | ||||||
|                         .setTaskName("Adding Files...") |  | ||||||
|                         .setUnit("MiB", 1048576); |  | ||||||
|  |  | ||||||
|                 try (ProgressBar pb = pbb.build()) { |       try (ProgressBar pb = pbb.build()) { | ||||||
|                   while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) { |         while (!progressMonitor.getState().equals(ProgressMonitor.State.READY)) { | ||||||
|                     pb.stepTo(progressMonitor.getWorkCompleted()); |           pb.stepTo(progressMonitor.getWorkCompleted()); | ||||||
|                     Thread.sleep(100); |           Thread.sleep(100); | ||||||
|                   } |         } | ||||||
|                   pb.stepTo(progressMonitor.getTotalWork()); |         pb.stepTo(progressMonitor.getTotalWork()); | ||||||
|                 } catch (Exception exception) { |       } catch (Exception exception) { | ||||||
|                   exception.printStackTrace(); |         logger.log(Logger.LogLevel.ERROR, exception.getMessage()); | ||||||
|                   onDone(); |         exception.printStackTrace(); | ||||||
|                 } |         onDone(); | ||||||
|                 progressMonitor.endProgressMonitor(); |       } | ||||||
|                 onDone(); |       progressMonitor.endProgressMonitor(); | ||||||
|               } catch (Exception ex) { |       onDone(); | ||||||
|                 ex.printStackTrace(); |     } catch (Exception ex) { | ||||||
|                 onDone(); |       logger.log(Logger.LogLevel.ERROR, ex.getMessage()); | ||||||
|               } |       ex.printStackTrace(); | ||||||
|             }); |       onDone(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | package net.horizoncode.sysbackup.tasks.impl; | ||||||
|  |  | ||||||
|  | import lombok.Getter; | ||||||
|  | import net.horizoncode.sysbackup.tasks.Task; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  | import java.time.Duration; | ||||||
|  | import java.time.temporal.ChronoUnit; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.Objects; | ||||||
|  |  | ||||||
|  | @Getter | ||||||
|  | public class VacuumTask extends Task { | ||||||
|  |  | ||||||
|  |   private final File backupDir; | ||||||
|  |   private final ChronoUnit unit; | ||||||
|  |   private final int value; | ||||||
|  |  | ||||||
|  |   public VacuumTask(File backupDir, ChronoUnit unit, int value) { | ||||||
|  |     this.backupDir = backupDir; | ||||||
|  |     this.unit = unit; | ||||||
|  |     this.value = value; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public void start() { | ||||||
|  |     if (backupDir.listFiles() != null) { | ||||||
|  |       Arrays.stream(Objects.requireNonNull(backupDir.listFiles())) | ||||||
|  |           .filter( | ||||||
|  |               file -> | ||||||
|  |                   file.lastModified() + Duration.of(value, unit).toMillis() | ||||||
|  |                       <= System.currentTimeMillis()) | ||||||
|  |           .forEachOrdered(File::deleteOnExit); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     onDone(); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -3,7 +3,6 @@ package net.horizoncode.sysbackup.threading; | |||||||
| import lombok.Getter; | import lombok.Getter; | ||||||
|  |  | ||||||
| import java.util.concurrent.ExecutorService; | import java.util.concurrent.ExecutorService; | ||||||
| import java.util.concurrent.ScheduledExecutorService; |  | ||||||
| import java.util.concurrent.ScheduledThreadPoolExecutor; | import java.util.concurrent.ScheduledThreadPoolExecutor; | ||||||
|  |  | ||||||
| public class ThreadPool { | public class ThreadPool { | ||||||
| @@ -11,13 +10,10 @@ public class ThreadPool { | |||||||
|   @Getter private final ExecutorService pool; |   @Getter private final ExecutorService pool; | ||||||
|  |  | ||||||
|   public ThreadPool(int corePoolSize, int maxPoolSize) { |   public ThreadPool(int corePoolSize, int maxPoolSize) { | ||||||
|     this.pool = scheduledExecutorService(corePoolSize, maxPoolSize); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   private ScheduledExecutorService scheduledExecutorService(int corePoolSize, int maxPoolSize) { |  | ||||||
|     ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = |     ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = | ||||||
|         new ScheduledThreadPoolExecutor(corePoolSize); |         new ScheduledThreadPoolExecutor(corePoolSize); | ||||||
|     scheduledThreadPoolExecutor.setMaximumPoolSize(maxPoolSize); |     scheduledThreadPoolExecutor.setMaximumPoolSize(maxPoolSize); | ||||||
|     return scheduledThreadPoolExecutor; |  | ||||||
|  |     this.pool = scheduledThreadPoolExecutor; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -2,6 +2,11 @@ | |||||||
| dateFormat = "yyyy-MM-dd HH-mm-ss" | dateFormat = "yyyy-MM-dd HH-mm-ss" | ||||||
| outputFile = "{date} - {taskName}" | outputFile = "{date} - {taskName}" | ||||||
|  |  | ||||||
|  | [vacuum] | ||||||
|  | enabled = true | ||||||
|  | time = 5 | ||||||
|  | unit = "DAYS" # See java.time.temporal.ChronoUnit | ||||||
|  |  | ||||||
| [mysql] | [mysql] | ||||||
| enabled = true | enabled = true | ||||||
| database = "magento" | database = "magento" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user