HADOOP-17665 Ignore missing keystore configuration in reloading mechanism

This commit is contained in:
Borislav Iordanov 2021-05-10 16:31:48 -04:00 committed by stack
parent 43db94c7a3
commit f5ef78d46f
3 changed files with 66 additions and 27 deletions

View File

@ -27,6 +27,7 @@
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
@ -582,7 +583,8 @@ private ServerConnector createHttpsChannelConnector(
conf.getLong(FileBasedKeyStoresFactory.SSL_STORES_RELOAD_INTERVAL_TPL_KEY, conf.getLong(FileBasedKeyStoresFactory.SSL_STORES_RELOAD_INTERVAL_TPL_KEY,
FileBasedKeyStoresFactory.DEFAULT_SSL_STORES_RELOAD_INTERVAL); FileBasedKeyStoresFactory.DEFAULT_SSL_STORES_RELOAD_INTERVAL);
if (storesReloadInterval > 0) { if (storesReloadInterval > 0 &&
(keyStore != null || trustStore != null)) {
this.configurationChangeMonitor = Optional.of( this.configurationChangeMonitor = Optional.of(
this.makeConfigurationChangeMonitor(storesReloadInterval, sslContextFactory)); this.makeConfigurationChangeMonitor(storesReloadInterval, sslContextFactory));
} }
@ -596,18 +598,26 @@ private ServerConnector createHttpsChannelConnector(
private Timer makeConfigurationChangeMonitor(long reloadInterval, private Timer makeConfigurationChangeMonitor(long reloadInterval,
SslContextFactory.Server sslContextFactory) { SslContextFactory.Server sslContextFactory) {
java.util.Timer timer = new java.util.Timer(FileBasedKeyStoresFactory.SSL_MONITORING_THREAD_NAME, true); java.util.Timer timer = new java.util.Timer(FileBasedKeyStoresFactory.SSL_MONITORING_THREAD_NAME, true);
ArrayList<Path> locations = new ArrayList<Path>();
if (keyStore != null) {
locations.add(Paths.get(keyStore));
}
if (trustStore != null) {
locations.add(Paths.get(trustStore));
}
// //
// The Jetty SSLContextFactory provides a 'reload' method which will reload both // The Jetty SSLContextFactory provides a 'reload' method which will reload both
// truststore and keystore certificates. // truststore and keystore certificates.
// //
timer.schedule(new FileMonitoringTimerTask( timer.schedule(new FileMonitoringTimerTask(
Paths.get(keyStore), locations,
path -> { path -> {
LOG.info("Reloading certificates from store keystore " + keyStore); LOG.info("Reloading keystore and truststore certificates.");
try { try {
sslContextFactory.reload(factory -> { }); sslContextFactory.reload(factory -> { });
} catch (Exception ex) { } catch (Exception ex) {
LOG.error("Failed to reload SSL keystore certificates", ex); LOG.error("Failed to reload SSL keystore " +
"and truststore certificates", ex);
} }
},null), },null),
reloadInterval, reloadInterval,

View File

@ -24,6 +24,9 @@
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -42,34 +45,59 @@ public class FileMonitoringTimerTask extends TimerTask {
static final String PROCESS_ERROR_MESSAGE = static final String PROCESS_ERROR_MESSAGE =
"Could not process file change : "; "Could not process file change : ";
final private Path filePath; final private List<Path> filePaths;
final private Consumer<Path> onFileChange; final private Consumer<Path> onFileChange;
final Consumer<Throwable> onChangeFailure; final Consumer<Throwable> onChangeFailure;
private long lastProcessed; private List<Long> lastProcessed;
/** /**
* Create file monitoring task to be scheduled using a standard Java {@link java.util.Timer} * See {@link #FileMonitoringTimerTask(List, Consumer, Consumer)}.
* instance.
* *
* @param filePath The path to the file to monitor. * @param filePath The file to monitor.
* @param onFileChange The function to call when the file has changed. * @param onFileChange What to do when the file changes.
* @param onChangeFailure The function to call when an exception is thrown during the * @param onChangeFailure What to do when <code>onFileChange</code>
* file change processing. * throws an exception.
*/ */
public FileMonitoringTimerTask(Path filePath, Consumer<Path> onFileChange, public FileMonitoringTimerTask(Path filePath, Consumer<Path> onFileChange,
Consumer<Throwable> onChangeFailure) { Consumer<Throwable> onChangeFailure) {
Preconditions.checkNotNull(filePath, "path to monitor disk file is not set"); this(Collections.singletonList(filePath), onFileChange, onChangeFailure);
Preconditions.checkNotNull(onFileChange, "action to monitor disk file is not set"); }
this.filePath = filePath; /**
this.lastProcessed = filePath.toFile().lastModified(); * Create file monitoring task to be scheduled using a standard
* Java {@link java.util.Timer} instance.
*
* @param filePaths The path to the file to monitor.
* @param onFileChange The function to call when the file has changed.
* @param onChangeFailure The function to call when an exception is
* thrown during the file change processing.
*/
public FileMonitoringTimerTask(List<Path> filePaths,
Consumer<Path> onFileChange,
Consumer<Throwable> onChangeFailure) {
Preconditions.checkNotNull(filePaths,
"path to monitor disk file is not set");
Preconditions.checkNotNull(onFileChange,
"action to monitor disk file is not set");
this.filePaths = new ArrayList<Path>(filePaths);
this.lastProcessed = new ArrayList<Long>();
this.filePaths.forEach(path ->
this.lastProcessed.add(path.toFile().lastModified()));
this.onFileChange = onFileChange; this.onFileChange = onFileChange;
this.onChangeFailure = onChangeFailure; this.onChangeFailure = onChangeFailure;
} }
@Override @Override
public void run() { public void run() {
if (lastProcessed != filePath.toFile().lastModified()) { int modified = -1;
for (int i = 0; i < filePaths.size() && modified < 0; i++) {
if (lastProcessed.get(i) != filePaths.get(i).toFile().lastModified()) {
modified = i;
}
}
if (modified > -1) {
Path filePath = filePaths.get(modified);
try { try {
onFileChange.accept(filePath); onFileChange.accept(filePath);
} catch (Throwable t) { } catch (Throwable t) {
@ -79,7 +107,7 @@ public void run() {
LOG.error(PROCESS_ERROR_MESSAGE + filePath.toString(), t); LOG.error(PROCESS_ERROR_MESSAGE + filePath.toString(), t);
} }
} }
lastProcessed = filePath.toFile().lastModified(); lastProcessed.set(modified, filePath.toFile().lastModified());
} }
} }
} }

View File

@ -246,4 +246,5 @@
<module>hadoop-yarn-ui</module> <module>hadoop-yarn-ui</module>
<module>hadoop-yarn-csi</module> <module>hadoop-yarn-csi</module>
</modules> </modules>
<!-- -->
</project> </project>