1. import java.io.*;
  2. import java.nio.file.*;
  3. import java.util.concurrent.Executors;
  4. import java.util.concurrent.ScheduledExecutorService;
  5. import java.util.concurrent.TimeUnit;
  6. public class ConfigWatcher {
  7. private final Path configFilePath;
  8. private final FileSystem fileSystem;
  9. private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
  10. private boolean running = true;
  11. public ConfigWatcher(Path configFilePath) {
  12. this.configFilePath = configFilePath;
  13. this.fileSystem = FileSystems.newFileSystem(configFilePath, new java.util.Properties());
  14. }
  15. public void start() {
  16. scheduler.scheduleAtFixedRate(this::checkConfigChanges, 0, 5, TimeUnit.SECONDS); // Check every 5 seconds
  17. }
  18. public void stop() {
  19. running = false;
  20. scheduler.shutdown();
  21. try {
  22. scheduler.awaitTermination(5, TimeUnit.SECONDS); //wait for tasks to complete
  23. } catch (InterruptedException e) {
  24. Thread.currentThread().interrupt();
  25. }
  26. fileSystem.close();
  27. }
  28. private void checkConfigChanges() {
  29. try {
  30. if (!running) return; //Exit if stopped
  31. Path configPath = configFilePath;
  32. try (InputStream inputStream = fileSystem.open(configPath);
  33. BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
  34. String currentContent = reader.lines().toString();
  35. // Simulate reading the previous content (in a real scenario, this would load from a persistent store)
  36. String previousContent = loadPreviousContent();
  37. if (!currentContent.equals(previousContent)) {
  38. System.out.println("Configuration file changed: " + configFilePath);
  39. // Perform data migration logic here
  40. performDataMigration();
  41. previousContent = currentContent; // Update previous content
  42. }
  43. } catch (IOException e) {
  44. System.err.println("Error reading configuration file: " + e.getMessage());
  45. }
  46. } catch (Exception e) {
  47. System.err.println("An unexpected error occurred: " + e.getMessage());
  48. }
  49. }
  50. private String loadPreviousContent() {
  51. //In a real application, this would load the previous content from a file or database.
  52. //For this example, we just return an empty string.
  53. return "";
  54. }
  55. private void performDataMigration() {
  56. System.out.println("Performing data migration...");
  57. //Add data migration code here.
  58. try {
  59. // Simulate data migration
  60. Thread.sleep(2000);
  61. System.out.println("Data migration complete.");
  62. } catch (InterruptedException e) {
  63. Thread.currentThread().interrupt();
  64. }
  65. }
  66. public static void main(String[] args) throws IOException {
  67. if (args.length != 1) {
  68. System.out.println("Usage: java ConfigWatcher <config_file_path>");
  69. System.exit(1);
  70. }
  71. Path configFilePath = Paths.get(args[0]);
  72. try (FileSystem fs = FileSystems.newFileSystem(configFilePath, new java.util.Properties())) {
  73. ConfigWatcher watcher = new ConfigWatcher(configFilePath);
  74. watcher.start();
  75. Runtime.getRuntime().addShutdownHook(new Thread(() -> {
  76. System.out.println("Shutting down ConfigWatcher...");
  77. watcher.stop();
  78. System.out.println("ConfigWatcher stopped.");
  79. }));
  80. while (true) {
  81. try {
  82. Thread.sleep(1000);
  83. } catch (InterruptedException e) {
  84. Thread.currentThread().interrupt();
  85. break;
  86. }
  87. }
  88. }
  89. }
  90. }

Add your comment