diff options
author | Amirsaman Memaripour <amirsaman.memaripour@10gen.com> | 2020-01-23 17:14:41 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-27 02:29:50 +0000 |
commit | e743135b6c87dc61ea91959633860f867aece528 (patch) | |
tree | adc3d666e7cda38a42814b653912bacbd4ab4a61 /src | |
parent | 1e62dde76309c37f8aae937f8782431177b90477 (diff) | |
download | mongo-e743135b6c87dc61ea91959633860f867aece528.tar.gz |
SERVER-45202 Improve command alias infrastructure
(cherry picked from commit 3cd3a6da3fe0b6f022b721094bda0b97c3527d23)
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/commands.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 22 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 15 |
3 files changed, 40 insertions, 14 deletions
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index b449af1b84a..5ba3eb11db1 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -555,11 +555,16 @@ std::unique_ptr<CommandInvocation> BasicCommand::parse(OperationContext* opCtx, return stdx::make_unique<Invocation>(opCtx, request, this); } -Command::Command(StringData name, StringData oldName) +Command::Command(StringData name, std::vector<StringData> aliases) : _name(name.toString()), + _aliases(std::move(aliases)), _commandsExecutedMetric("commands." + _name + ".total", &_commandsExecuted), _commandsFailedMetric("commands." + _name + ".failed", &_commandsFailed) { - globalCommandRegistry()->registerCommand(this, name, oldName); + globalCommandRegistry()->registerCommand(this, _name, _aliases); +} + +bool Command::hasAlias(const StringData& alias) const { + return globalCommandRegistry()->findCommand(alias) == this; } Status BasicCommand::explain(OperationContext* opCtx, @@ -610,8 +615,12 @@ bool ErrmsgCommandDeprecated::run(OperationContext* opCtx, ////////////////////////////////////////////////////////////// // CommandRegistry -void CommandRegistry::registerCommand(Command* command, StringData name, StringData oldName) { - for (StringData key : {name, oldName}) { +void CommandRegistry::registerCommand(Command* command, + StringData name, + std::vector<StringData> aliases) { + aliases.push_back(name); + + for (auto key : aliases) { if (key.empty()) { continue; } diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index 1ecd810911c..bade5650496 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -259,9 +259,15 @@ public: * Constructs a new command and causes it to be registered with the global commands list. It is * not safe to construct commands other than when the server is starting up. * - * @param oldName an optional old, deprecated name for the command + * @param oldName an old, deprecated name for the command */ - Command(StringData name, StringData oldName = StringData()); + Command(StringData name, StringData oldName) + : Command(name, std::vector<StringData>({oldName})) {} + + /** + * @param aliases the optional list of aliases (e.g., old names) for the command + */ + Command(StringData name, std::vector<StringData> aliases = {}); // Do not remove or relocate the definition of this "key function". // See https://gcc.gnu.org/wiki/VerboseDiagnostics#missing_vtable @@ -330,7 +336,7 @@ public: /** * Return true if the command requires auth. - */ + */ virtual bool requiresAuth() const { return true; } @@ -409,10 +415,18 @@ public: rpc::ReplyBuilderInterface* replyBuilder, const Command& command); + /** + * Checks if the command is also known by the provided alias. + */ + bool hasAlias(const StringData& alias) const; + private: // The full name of the command const std::string _name; + // The list of aliases for the command + const std::vector<StringData> _aliases; + // Counters for how many times this command has been executed and failed mutable Counter64 _commandsExecuted; mutable Counter64 _commandsFailed; @@ -851,7 +865,7 @@ public: return _commands; } - void registerCommand(Command* command, StringData name, StringData oldName); + void registerCommand(Command* command, StringData name, std::vector<StringData> aliases); Command* findCommand(StringData name) const; diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index a9a4958701d..a50743e0f1d 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -131,7 +131,10 @@ const StringMap<int> sessionCheckoutWhitelist = {{"abortTransaction", 1}, {"refreshLogicalSessionCacheNow", 1}, {"update", 1}}; -bool shouldActivateFailCommandFailPoint(const BSONObj& data, StringData cmdName, Client* client) { +bool shouldActivateFailCommandFailPoint(const BSONObj& data, + const CommandInvocation* invocation, + Client* client) { + auto cmdName = invocation->definition()->getName(); if (cmdName == "configureFailPoint"_sd) // Banned even if in failCommands. return false; @@ -569,8 +572,7 @@ bool runCommandImpl(OperationContext* opCtx, auto waitForWriteConcern = [&](auto&& bb) { MONGO_FAIL_POINT_BLOCK_IF(failCommand, data, [&](const BSONObj& data) { - return shouldActivateFailCommandFailPoint( - data, request.getCommandName(), opCtx->getClient()) && + return shouldActivateFailCommandFailPoint(data, invocation, opCtx->getClient()) && data.hasField("writeConcernError"); }) { bb.append(data.getData()["writeConcernError"]); @@ -635,12 +637,13 @@ bool runCommandImpl(OperationContext* opCtx, /** * Maybe uassert according to the 'failCommand' fail point. */ -void evaluateFailCommandFailPoint(OperationContext* opCtx, StringData commandName) { +void evaluateFailCommandFailPoint(OperationContext* opCtx, const CommandInvocation* invocation) { MONGO_FAIL_POINT_BLOCK_IF(failCommand, data, [&](const BSONObj& data) { - return shouldActivateFailCommandFailPoint(data, commandName, opCtx->getClient()) && + return shouldActivateFailCommandFailPoint(data, invocation, opCtx->getClient()) && (data.hasField("closeConnection") || data.hasField("errorCode")); }) { bool closeConnection; + auto commandName = invocation->definition()->getName(); if (bsonExtractBooleanField(data.getData(), "closeConnection", &closeConnection).isOK() && closeConnection) { opCtx->getClient()->session()->end(); @@ -697,7 +700,7 @@ void execCommandDatabase(OperationContext* opCtx, replCoord->getReplicationMode() == repl::ReplicationCoordinator::modeReplSet, opCtx->getServiceContext()->getStorageEngine()->supportsDocLocking()); - evaluateFailCommandFailPoint(opCtx, command->getName()); + evaluateFailCommandFailPoint(opCtx, invocation.get()); const auto dbname = request.getDatabase().toString(); uassert( |