Add support for symlinks in FileWatcher

This commit allows using symlinks for SSL certificate hot reloading.

See gh-43586
This commit is contained in:
Tomasz Maciejewski 2024-12-20 20:39:11 +01:00 committed by Stéphane Nicoll
parent 0035569882
commit 26ca3790b2
2 changed files with 24 additions and 1 deletions

View File

@ -86,7 +86,7 @@ class FileWatcher implements Closeable {
this.thread = new WatcherThread(); this.thread = new WatcherThread();
this.thread.start(); this.thread.start();
} }
this.thread.register(new Registration(paths, action)); this.thread.register(new Registration(resolveSymlinks(paths), action));
} }
catch (IOException ex) { catch (IOException ex) {
throw new UncheckedIOException("Failed to register paths for watching: " + paths, ex); throw new UncheckedIOException("Failed to register paths for watching: " + paths, ex);
@ -94,6 +94,17 @@ class FileWatcher implements Closeable {
} }
} }
private Set<Path> resolveSymlinks(Set<Path> paths) throws IOException {
Set<Path> result = new HashSet<>();
for (Path path : paths) {
result.add(path);
if (Files.isSymbolicLink(path)) {
result.add(Files.readSymbolicLink(path));
}
}
return result;
}
@Override @Override
public void close() throws IOException { public void close() throws IOException {
synchronized (this.lock) { synchronized (this.lock) {

View File

@ -94,6 +94,18 @@ class FileWatcherTests {
callback.expectChanges(); callback.expectChanges();
} }
@Test
void shouldFollowSymlink(@TempDir Path tempDir) throws Exception {
Path realFile = tempDir.resolve("realFile.txt");
Path symLink = tempDir.resolve("symlink.txt");
Files.createFile(realFile);
Files.createSymbolicLink(symLink, realFile);
WaitingCallback callback = new WaitingCallback();
this.fileWatcher.watch(Set.of(symLink), callback);
Files.writeString(realFile, "Some content");
callback.expectChanges();
}
@Test @Test
void shouldIgnoreNotWatchedFiles(@TempDir Path tempDir) throws Exception { void shouldIgnoreNotWatchedFiles(@TempDir Path tempDir) throws Exception {
Path watchedFile = tempDir.resolve("watched.txt"); Path watchedFile = tempDir.resolve("watched.txt");