Improved KeyStoreScanner.scan().

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2020-12-02 19:24:19 +01:00
parent fe0e076055
commit 9c882ee796
2 changed files with 15 additions and 19 deletions

View File

@ -20,7 +20,7 @@ package org.eclipse.jetty.util.ssl;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -119,23 +119,18 @@ public class KeyStoreScanner extends ContainerLifeCycle implements Scanner.Discr
} }
@ManagedOperation(value = "Scan for changes in the SSL Keystore", impact = "ACTION") @ManagedOperation(value = "Scan for changes in the SSL Keystore", impact = "ACTION")
public boolean scan() public boolean scan(long waitMillis)
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("scanning"); LOG.debug("scanning");
CompletableFuture<Boolean> cf = new CompletableFuture<>();
try try
{ {
CountDownLatch complete = new CountDownLatch(2); // Perform 2 scans to be sure that the scan is stable.
Callback callback = Callback.from(complete::countDown, t -> _scanner.scan(Callback.from(() ->
{ _scanner.scan(Callback.from(() -> cf.complete(true), cf::completeExceptionally)), cf::completeExceptionally));
LOG.warn("Scan fail", t); return cf.get(waitMillis, TimeUnit.MILLISECONDS);
complete.countDown();
});
_scanner.scan(callback);
_scanner.scan(callback);
return complete.await(10, TimeUnit.SECONDS);
} }
catch (Exception e) catch (Exception e)
{ {
@ -152,7 +147,8 @@ public class KeyStoreScanner extends ContainerLifeCycle implements Scanner.Discr
try try
{ {
sslContextFactory.reload(scf -> sslContextFactory.reload(scf ->
{}); {
});
} }
catch (Throwable t) catch (Throwable t)
{ {

View File

@ -126,7 +126,7 @@ public class KeyStoreScannerTest
// Switch to use newKeystore which has a later expiry date. // Switch to use newKeystore which has a later expiry date.
useKeystore("newKeystore"); useKeystore("newKeystore");
assertTrue(keystoreScanner.scan()); assertTrue(keystoreScanner.scan(5000));
// The scanner should have detected the updated keystore, expiry should be renewed. // The scanner should have detected the updated keystore, expiry should be renewed.
X509Certificate cert2 = getCertificateFromServer(); X509Certificate cert2 = getCertificateFromServer();
@ -146,7 +146,7 @@ public class KeyStoreScannerTest
try (StacklessLogging ignored = new StacklessLogging(KeyStoreScanner.class)) try (StacklessLogging ignored = new StacklessLogging(KeyStoreScanner.class))
{ {
useKeystore("badKeystore"); useKeystore("badKeystore");
keystoreScanner.scan(); keystoreScanner.scan(5000);
} }
// The good keystore is removed, now the bad keystore now causes an exception. // The good keystore is removed, now the bad keystore now causes an exception.
@ -167,7 +167,7 @@ public class KeyStoreScannerTest
{ {
Path keystorePath = keystoreDir.resolve("keystore"); Path keystorePath = keystoreDir.resolve("keystore");
assertTrue(Files.deleteIfExists(keystorePath)); assertTrue(Files.deleteIfExists(keystorePath));
keystoreScanner.scan(); keystoreScanner.scan(5000);
} }
// The good keystore is removed, having no keystore causes an exception. // The good keystore is removed, having no keystore causes an exception.
@ -175,7 +175,7 @@ public class KeyStoreScannerTest
// Switch to use keystore2 which has a later expiry date. // Switch to use keystore2 which has a later expiry date.
useKeystore("newKeystore"); useKeystore("newKeystore");
keystoreScanner.scan(); keystoreScanner.scan(5000);
X509Certificate cert2 = getCertificateFromServer(); X509Certificate cert2 = getCertificateFromServer();
assertThat(getExpiryYear(cert2), is(2020)); assertThat(getExpiryYear(cert2), is(2020));
} }
@ -200,7 +200,7 @@ public class KeyStoreScannerTest
// Change the symlink to point to the newKeystore file location which has a later expiry date. // Change the symlink to point to the newKeystore file location which has a later expiry date.
Files.delete(keystorePath); Files.delete(keystorePath);
Files.createSymbolicLink(keystorePath, useKeystore("newKeystore")); Files.createSymbolicLink(keystorePath, useKeystore("newKeystore"));
keystoreScanner.scan(); keystoreScanner.scan(5000);
// The scanner should have detected the updated keystore, expiry should be renewed. // The scanner should have detected the updated keystore, expiry should be renewed.
X509Certificate cert2 = getCertificateFromServer(); X509Certificate cert2 = getCertificateFromServer();
@ -232,7 +232,7 @@ public class KeyStoreScannerTest
// Change the target file of the symlink to the newKeystore which has a later expiry date. // Change the target file of the symlink to the newKeystore which has a later expiry date.
Files.copy(newKeystoreSrc, target, StandardCopyOption.REPLACE_EXISTING); Files.copy(newKeystoreSrc, target, StandardCopyOption.REPLACE_EXISTING);
System.err.println("### Triggering scan"); System.err.println("### Triggering scan");
keystoreScanner.scan(); keystoreScanner.scan(5000);
// The scanner should have detected the updated keystore, expiry should be renewed. // The scanner should have detected the updated keystore, expiry should be renewed.
X509Certificate cert2 = getCertificateFromServer(); X509Certificate cert2 = getCertificateFromServer();