diff options
author | Kaitlin Mahar <kaitlin.mahar@mongodb.com> | 2017-12-07 14:56:25 -0500 |
---|---|---|
committer | Kaitlin Mahar <kaitlin.mahar@mongodb.com> | 2017-12-13 11:41:02 -0500 |
commit | 65c64a7845ca8159028148b25d3ec1867158108d (patch) | |
tree | dc8f4abd70848187b906d9b76bcad4b15faaf05b /src/mongo/db/keys_collection_manager.h | |
parent | 33bf1580977524b1beb84f9bcedd51547c68aeb4 (diff) | |
download | mongo-65c64a7845ca8159028148b25d3ec1867158108d.tar.gz |
SERVER-31316 Remove unused code and unnecessary inheritance in KeysCollectionManager* classes
Diffstat (limited to 'src/mongo/db/keys_collection_manager.h')
-rw-r--r-- | src/mongo/db/keys_collection_manager.h | 142 |
1 files changed, 134 insertions, 8 deletions
diff --git a/src/mongo/db/keys_collection_manager.h b/src/mongo/db/keys_collection_manager.h index 4d6771be838..3cdac7b9bf2 100644 --- a/src/mongo/db/keys_collection_manager.h +++ b/src/mongo/db/keys_collection_manager.h @@ -31,34 +31,47 @@ #include <memory> #include "mongo/base/status_with.h" +#include "mongo/db/keys_collection_cache_reader.h" +#include "mongo/db/keys_collection_cache_reader_and_updater.h" #include "mongo/db/keys_collection_document.h" +#include "mongo/stdx/functional.h" +#include "mongo/stdx/mutex.h" +#include "mongo/stdx/thread.h" +#include "mongo/util/concurrency/notification.h" +#include "mongo/util/duration.h" namespace mongo { class OperationContext; class LogicalTime; class ServiceContext; +class KeysCollectionClient; extern int KeysRotationIntervalSec; + /** - * This is responsible for providing keys that can be used for HMAC computation. This also supports - * automatic key rotation that happens on a configurable interval. + * The KeysCollectionManager queries the config servers for keys that can be used for + * HMAC computation. It maintains an internal background thread that is used to periodically + * refresh the local key cache against the keys collection stored on the config servers. */ class KeysCollectionManager { public: static const Seconds kKeyValidInterval; static const std::string kKeyManagerPurposeString; - virtual ~KeysCollectionManager(); + KeysCollectionManager(std::string purpose, + std::unique_ptr<KeysCollectionClient> client, + Seconds keyValidForInterval); /** * Return a key that is valid for the given time and also matches the keyId. Note that this call - * can block if it will need to do a refresh and we are on a sharded cluster. + * can block if it will need to do a refresh. * * Throws ErrorCode::ExceededTimeLimit if it times out. */ - virtual StatusWith<KeysCollectionDocument> getKeyForValidation( - OperationContext* opCtx, long long keyId, const LogicalTime& forThisTime) = 0; + StatusWith<KeysCollectionDocument> getKeyForValidation(OperationContext* opCtx, + long long keyId, + const LogicalTime& forThisTime); /** * Returns a key that is valid for the given time. Note that unlike getKeyForValidation, this @@ -66,8 +79,121 @@ public: * * Throws ErrorCode::ExceededTimeLimit if it times out. */ - virtual StatusWith<KeysCollectionDocument> getKeyForSigning(OperationContext* opCtx, - const LogicalTime& forThisTime) = 0; + StatusWith<KeysCollectionDocument> getKeyForSigning(OperationContext* opCtx, + const LogicalTime& forThisTime); + + /** + * Request this manager to perform a refresh. + */ + void refreshNow(OperationContext* opCtx); + + /** + * Starts a background thread that will constantly update the internal cache of keys. + * + * Cannot call this after stopMonitoring was called at least once. + */ + void startMonitoring(ServiceContext* service); + + /** + * Stops the background thread updating the cache. + */ + void stopMonitoring(); + + /** + * Enable writing new keys to the config server primary. Should only be called if current node + * is the config primary. + */ + void enableKeyGenerator(OperationContext* opCtx, bool doEnable); + + /** + * Returns true if the refresher has ever successfully returned keys from the config server. + */ + bool hasSeenKeys(); + +private: + /** + * This is responsible for periodically performing refresh in the background. + */ + class PeriodicRunner { + public: + using RefreshFunc = stdx::function<StatusWith<KeysCollectionDocument>(OperationContext*)>; + + /** + * Preemptively inform the monitoring thread it needs to perform a refresh. Returns an + * object + * that gets notified after the current round of refresh is over. Note that being notified + * can + * mean either of these things: + * + * 1. An error occurred and refresh was not performed. + * 2. No error occurred but no new key was found. + * 3. No error occurred and new keys were found. + */ + void refreshNow(OperationContext* opCtx); + + /** + * Sets the refresh function to use. + * Should only be used to bootstrap this refresher with initial strategy. + */ + void setFunc(RefreshFunc newRefreshStrategy); + + /** + * Switches the current strategy with a new one. This also waits to make sure that the old + * strategy is not being used and will no longer be used after this call. + */ + void switchFunc(OperationContext* opCtx, RefreshFunc newRefreshStrategy); + + /** + * Starts the refresh thread. + */ + void start(ServiceContext* service, + const std::string& threadName, + Milliseconds refreshInterval); + + /** + * Stops the refresh thread. + */ + void stop(); + + /** + * Returns true if keys have ever successfully been returned from the config server. + */ + bool hasSeenKeys(); + + private: + void _doPeriodicRefresh(ServiceContext* service, + std::string threadName, + Milliseconds refreshInterval); + + stdx::mutex _mutex; // protects all the member variables below. + std::shared_ptr<Notification<void>> _refreshRequest; + stdx::condition_variable _refreshNeededCV; + + stdx::thread _backgroundThread; + std::shared_ptr<RefreshFunc> _doRefresh; + + bool _hasSeenKeys = false; + bool _inShutdown = false; + }; + + /** + * Return a key that is valid for the given time and also matches the keyId. + */ + StatusWith<KeysCollectionDocument> _getKeyWithKeyIdCheck(long long keyId, + const LogicalTime& forThisTime); + + /** + * Return a key that is valid for the given time. + */ + StatusWith<KeysCollectionDocument> _getKey(const LogicalTime& forThisTime); + + std::unique_ptr<KeysCollectionClient> _client; + const std::string _purpose; + const Seconds _keyValidForInterval; + + // No mutex needed since the members below have their own mutexes. + KeysCollectionCacheReader _keysCache; + PeriodicRunner _refresher; }; } // namespace mongo |