private FileChangeWatcher newFileChangeWatcher(String fileLocation) throws IOException { if (fileLocation == null || fileLocation.isEmpty()) { return null; } final Path filePath = Paths.get(fileLocation).toAbsolutePath(); Path parentPath = filePath.getParent(); if (parentPath == null) { throw new IOException( "Key/trust store path does not have a parent: " + filePath); } return new FileChangeWatcher( parentPath, watchEvent -> { handleWatchEvent(filePath, watchEvent); }); }
/** * Disables automatic reloading of the trust store and key store files when they change on disk. * Stops background threads and closes WatchService instances. */ @Override public void close() { if (keyStoreFileWatcher != null) { keyStoreFileWatcher.stop(); keyStoreFileWatcher = null; } if (trustStoreFileWatcher != null) { trustStoreFileWatcher.stop(); trustStoreFileWatcher = null; } }
/** * Tells the background thread to stop. Does not wait for it to exit. */ public void stop() { if (compareAndSetState( new State[]{State.RUNNING, State.STARTING}, State.STOPPING)) { watcherThread.interrupt(); } }
try { final AtomicInteger callCount = new AtomicInteger(0); watcher = new FileChangeWatcher( tempDir.toPath(), event -> { watcher.start(); watcher.waitForState(FileChangeWatcher.State.RUNNING); } finally { if (watcher != null) { watcher.stop(); watcher.waitForState(FileChangeWatcher.State.STOPPED);
/** * Enables automatic reloading of the trust store and key store files when they change on disk. * * @throws IOException if creating the FileChangeWatcher objects fails. */ public void enableCertFileReloading() throws IOException { LOG.info("enabling cert file reloading"); ZKConfig config = zkConfig == null ? new ZKConfig() : zkConfig; FileChangeWatcher newKeyStoreFileWatcher = newFileChangeWatcher(config.getProperty(sslKeystoreLocationProperty)); if (newKeyStoreFileWatcher != null) { // stop old watcher if there is one if (keyStoreFileWatcher != null) { keyStoreFileWatcher.stop(); } keyStoreFileWatcher = newKeyStoreFileWatcher; keyStoreFileWatcher.start(); } FileChangeWatcher newTrustStoreFileWatcher = newFileChangeWatcher(config.getProperty(sslTruststoreLocationProperty)); if (newTrustStoreFileWatcher != null) { // stop old watcher if there is one if (trustStoreFileWatcher != null) { trustStoreFileWatcher.stop(); } trustStoreFileWatcher = newTrustStoreFileWatcher; trustStoreFileWatcher.start(); } }
/** * Atomically sets the state to <code>update</code> if and only if the * state is currently <code>expected</code>. * @param expected the expected state. * @param update the new state. * @return true if the update succeeds, or false if the current state * does not equal <code>expected</code>. */ private synchronized boolean compareAndSetState(State expected, State update) { if (state == expected) { setState(update); return true; } else { return false; } }
private void runLoop() { while (FileChangeWatcher.this.getState() == FileChangeWatcher.State.RUNNING) { WatchKey key; try {
try { final List<WatchEvent<?>> events = new ArrayList<>(); watcher = new FileChangeWatcher( tempDir.toPath(), event -> { watcher.start(); watcher.waitForState(FileChangeWatcher.State.RUNNING); watcher.stop(); watcher.waitForState(FileChangeWatcher.State.STOPPED);
/** * Atomically sets the state to <code>update</code> if and only if the * state is currently one of <code>expectedStates</code>. * @param expectedStates the expected states. * @param update the new state. * @return true if the update succeeds, or false if the current state * does not equal any of the <code>expectedStates</code>. */ private synchronized boolean compareAndSetState(State[] expectedStates, State update) { for (State expected : expectedStates) { if (state == expected) { setState(update); return true; } } return false; }
@Override public void run() { try { LOG.info(getName() + " thread started"); if (!compareAndSetState( FileChangeWatcher.State.STARTING, FileChangeWatcher.State.RUNNING)) { // stop() called shortly after start(), before // this thread started running. FileChangeWatcher.State state = FileChangeWatcher.this.getState(); if (state != FileChangeWatcher.State.STOPPING) { throw new IllegalStateException("Unexpected state: " + state); } return; } runLoop(); } catch (Exception e) { LOG.warn("Error in runLoop()", e); throw e; } finally { try { watchService.close(); } catch (IOException e) { LOG.warn("Error closing watch service", e); } LOG.info(getName() + " thread finished"); FileChangeWatcher.this.setState(FileChangeWatcher.State.STOPPED); } }
try { final List<WatchEvent<?>> events = new ArrayList<>(); watcher = new FileChangeWatcher( tempDir.toPath(), event -> { watcher.start(); watcher.waitForState(FileChangeWatcher.State.RUNNING); watcher.stop(); watcher.waitForState(FileChangeWatcher.State.STOPPED);
/** * Tells the background thread to start. Does not wait for it to be running. * Calling this method more than once has no effect. */ public void start() { if (!compareAndSetState(State.NEW, State.STARTING)) { // If previous state was not NEW, start() has already been called. return; } this.watcherThread.start(); }
try { final List<WatchEvent<?>> events = new ArrayList<>(); watcher = new FileChangeWatcher( tempDir.toPath(), event -> { watcher.start(); watcher.waitForState(FileChangeWatcher.State.RUNNING); watcher.stop(); watcher.waitForState(FileChangeWatcher.State.STOPPED);
try { final List<WatchEvent<?>> events = new ArrayList<>(); watcher = new FileChangeWatcher( tempDir.toPath(), event -> { watcher.start(); watcher.waitForState(FileChangeWatcher.State.RUNNING); watcher.stop(); watcher.waitForState(FileChangeWatcher.State.STOPPED);