Search code examples
spring-boot

Monitor file changes from Spring boot project


I have this Java code which I want to use to monitor file changes into directory:

private static String folderPath = "D:\\Import";

public static void main(final String[] args) throws IOException, InterruptedException {

    System.out.println("Running file verifier");
    System.out.println("monitoring folder " + folderPath);
    EntityImportRequestsJob sql = new EntityImportRequestsJob();

    WatchService watchService = FileSystems.getDefault().newWatchService();
    Path path = Paths.get(folderPath);
    path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
    WatchKey key;

    while ((key = watchService.take()) != null) {
        for (WatchEvent<?> event : key.pollEvents()) {
            System.out.println("Event kind:" + event.kind() + ". File affected: " + event.context() + ".");
            
            if (event.kind().equals(StandardWatchEventKinds.ENTRY_DELETE)) {
                Instant start = Instant.now();

                boolean flag = true;

                while(flag) {
                    while ((key = watchService.take()) != null) {
                        HashMap<String, List> map = sql.checkFileImport();

                        List values = map.get(event.context()); // get values by file name
                        if(values.contains("Completed")){
                            // exit the monitoring while loop
                            flag = false;
                        }
                    }
                    Thread.sleep(1000);
                }

                Instant end = Instant.now();
                System.out.println(Duration.between(start,end));

                long seconds = TimeUnit.MILLISECONDS.toSeconds(Duration.between(start,end).getSeconds());
                long minutes = TimeUnit.MILLISECONDS.toMinutes(Duration.between(start,end).getSeconds());

                System.out.format("Execution time %d minutes %d seconds", minutes, seconds);
            }

        }

        key.reset();
    }

    watchService.close();
}

How I can start this code when Spring Project is successfully started?


Solution

  • You can start this code when a Spring project is successfully started by creating a Bean for it and annotating it with @EventListener and ApplicationReadyEvent like this:

    @Component
    public class FileMonitor {
        private static String folderPath = "D:\\Import";
    
        @EventListener(ApplicationReadyEvent.class)
        public void startMonitoring() throws IOException, InterruptedException {
            System.out.println("Running file verifier");
            System.out.println("monitoring folder " + folderPath);
            EntitiesImportRequestsJob sql = new EntitiesImportRequestsJob();
    
            WatchService watchService = FileSystems.getDefault().newWatchService();
            Path path = Paths.get(folderPath);
            path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, StandardWatchEventKinds.ENTRY_MODIFY);
            WatchKey key;
    
            while ((key = watchService.take()) != null) {
                for (WatchEvent<?> event : key.pollEvents()) {
                    System.out.println("Event kind:" + event.kind() + ". File affected: " + event.context() + ".");
    
                    if (event.kind().equals(StandardWatchEventKinds.ENTRY_DELETE)) {
                        Instant start = Instant.now();
    
                        boolean flag = true;
    
                        while(flag) {
                            while ((key = watchService.take()) != null) {
                                HashMap<String, List> map = sql.checkFileImport();
    
                                List values = map.get(event.context()); // get values by file name
                                if(values.contains("Completed")){
                                    // exit the monitoring while loop
                                    flag = false;
                                }
                            }
                            Thread.sleep(1000);
                        }
    
                        Instant end = Instant.now();
                        System.out.println(Duration.between(start,end));
    
                        long seconds = TimeUnit.MILLISECONDS.toSeconds(Duration.between(start,end).getSeconds());
                        long minutes = TimeUnit.MILLISECONDS.toMinutes(Duration.between(start,end).getSeconds());
    
                        System.out.format("Execution time %d minutes %d seconds", minutes, seconds);
                    }
    
                }
    
                key.reset();
            }
    
            watchService.close();
        }
    }
    

    Make sure the FileMonitor class is in a package that is scanned by Spring.

    And also make sure EntitiesImportRequestsJob is properly instantiated and managed by spring container, otherwise you will get a NullPointerException