Browse Source

Merge pull request #43586 from tmaciejewski

* pr/43586:
  Polish "Add support for symlinks in FileWatcher"
  Add support for symlinks in FileWatcher

Closes gh-43586
pull/43904/head
Stéphane Nicoll 1 year ago
parent
commit
a5b917f9aa
  1. 16
      spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/FileWatcher.java
  2. 28
      spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/FileWatcherTests.java

16
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/FileWatcher.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2023 the original author or authors. * Copyright 2012-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -86,7 +86,11 @@ 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)); Set<Path> actualPaths = new HashSet<>();
for (Path path : paths) {
actualPaths.add(resolveSymlinkIfNecessary(path));
}
this.thread.register(new Registration(actualPaths, 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 +98,14 @@ class FileWatcher implements Closeable {
} }
} }
private static Path resolveSymlinkIfNecessary(Path path) throws IOException {
if (Files.isSymbolicLink(path)) {
Path target = Files.readSymbolicLink(path);
return resolveSymlinkIfNecessary(target);
}
return path;
}
@Override @Override
public void close() throws IOException { public void close() throws IOException {
synchronized (this.lock) { synchronized (this.lock) {

28
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ssl/FileWatcherTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2023 the original author or authors. * Copyright 2012-2024 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -94,6 +94,32 @@ 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
void shouldFollowSymlinkRecursively(@TempDir Path tempDir) throws Exception {
Path realFile = tempDir.resolve("realFile.txt");
Path symLink = tempDir.resolve("symlink.txt");
Path symLink2 = tempDir.resolve("symlink2.txt");
Files.createFile(realFile);
Files.createSymbolicLink(symLink, symLink2);
Files.createSymbolicLink(symLink2, 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");

Loading…
Cancel
Save