Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.crypto.key.KeyProvider;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.util.KMSUtil;

import org.apache.hadoop.classification.VisibleForTesting;
Expand All @@ -34,6 +35,7 @@
import org.apache.hadoop.thirdparty.com.google.common.cache.RemovalListener;
import org.apache.hadoop.thirdparty.com.google.common.cache.RemovalNotification;

import org.apache.hadoop.util.ShutdownHookManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -65,6 +67,9 @@ public void onRemoval(
}
})
.build();

ShutdownHookManager.get().addShutdownHook(new KeyProviderCacheFinalizer(),
SHUTDOWN_HOOK_PRIORITY);
}

public KeyProvider get(final Configuration conf,
Expand All @@ -85,6 +90,26 @@ public KeyProvider call() throws Exception {
}
}

public static final int SHUTDOWN_HOOK_PRIORITY = FileSystem.SHUTDOWN_HOOK_PRIORITY - 1;

private class KeyProviderCacheFinalizer implements Runnable {
@Override
public synchronized void run() {
invalidateCache();
}
}

/**
* Invalidate cache. KeyProviders in the cache will be closed by cache hook.
*/
@VisibleForTesting
synchronized void invalidateCache() {
LOG.debug("Invalidating all cached KeyProviders.");
if (cache != null) {
cache.invalidateAll();
}
}

private URI createKeyProviderURI(Configuration conf) {
final String providerUriStr = conf.getTrimmed(
CommonConfigurationKeysPublic.HADOOP_SECURITY_KEY_PROVIDER_PATH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public class TestKeyProviderCache {

public static class DummyKeyProvider extends KeyProvider {

public static int CLOSE_CALL_COUNT = 0;

public DummyKeyProvider(Configuration conf) {
super(conf);
}
Expand Down Expand Up @@ -76,6 +78,10 @@ public KeyVersion rollNewVersion(String name, byte[] material)
public void flush() throws IOException {
}

@Override
public void close() {
CLOSE_CALL_COUNT += 1;
}
}

public static class Factory extends KeyProviderFactory {
Expand Down Expand Up @@ -124,6 +130,9 @@ public void testCache() throws Exception {
Assert.assertFalse("Same KeyProviders returned !!",
keyProvider1 == keyProvider4);

kpCache.invalidateCache();
Assert.assertEquals("Expected number of closing calls doesn't match",
3, DummyKeyProvider.CLOSE_CALL_COUNT);
}

private URI getKeyProviderUriFromConf(Configuration conf) {
Expand Down