From 8ec2a851c8fb250ad69f020313633b0cf68346e4 Mon Sep 17 00:00:00 2001 From: Ali Mir Date: Wed, 23 Sep 2020 18:18:26 +0000 Subject: SERVER-51106 Make the isMaster command a derived class of hello (cherry picked from commit e178007c01565bf59d038f3be1566da036c60397) --- src/mongo/db/commands/generic.cpp | 6 ++-- src/mongo/db/repl/replication_info.cpp | 43 ++++++++++++++++++++------ src/mongo/s/commands/cluster_is_master_cmd.cpp | 30 +++++++++++++----- 3 files changed, 57 insertions(+), 22 deletions(-) diff --git a/src/mongo/db/commands/generic.cpp b/src/mongo/db/commands/generic.cpp index 4940d1106dd..c1312768ee1 100644 --- a/src/mongo/db/commands/generic.cpp +++ b/src/mongo/db/commands/generic.cpp @@ -284,10 +284,8 @@ public: // Sort the command names before building the result BSON. std::vector commandNames; for (const auto command : allCommands()) { - // Don't show oldnames unless it's "isMaster". The output of the listCommands command - // must include "isMaster," even though it's an alias for the "hello" command, in order - // to preserve backwards compatibility with Ops Manager 4.4. - if (command.first == command.second->getName() || command.first == kIsMasterString) + // Don't show oldnames + if (command.first == command.second->getName()) commandNames.push_back(command.first); } std::sort(commandNames.begin(), commandNames.end()); diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index c3b740de811..7ff6038b8a2 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -72,7 +72,6 @@ namespace repl { namespace { constexpr auto kHelloString = "hello"_sd; -// Aliases for the hello command in order to provide backwards compatibility. constexpr auto kCamelCaseIsMasterString = "isMaster"_sd; constexpr auto kLowerCaseIsMasterString = "ismaster"_sd; @@ -225,9 +224,9 @@ public: } } oplogInfoServerStatus; -class CmdHello final : public BasicCommand { +class CmdHello : public BasicCommand { public: - CmdHello() : BasicCommand(kHelloString, {kCamelCaseIsMasterString, kLowerCaseIsMasterString}) {} + CmdHello() : CmdHello(kHelloString, {}) {} bool requiresAuth() const override { return false; @@ -238,7 +237,7 @@ public: virtual void help(stringstream& help) const { help << "Check if this server is primary for a replica pair/set; also if it is --master or " "--slave in simple master/slave setups.\n"; - help << "{ isMaster : 1 }"; + help << "{ hello : 1 }"; } virtual bool supportsWriteConcern(const BSONObj& cmd) const override { return false; @@ -257,11 +256,6 @@ public: LastError::get(opCtx->getClient()).disable(); } - // Parse the command name, which should be one of the following: hello, isMaster, or - // ismaster. If the command is "hello", we must attach an "isWritablePrimary" response field - // instead of "ismaster" and "secondaryDelaySecs" response field instead of "slaveDelay". - bool useLegacyResponseFields = (cmdObj.firstElementFieldName() != kHelloString); - transport::Session::TagMask sessionTagsToSet = 0; transport::Session::TagMask sessionTagsToUnset = 0; @@ -377,7 +371,7 @@ public: }); } - appendReplicationInfo(opCtx, result, 0, useLegacyResponseFields); + appendReplicationInfo(opCtx, result, 0, useLegacyResponseFields()); if (serverGlobalParams.clusterRole == ClusterRole::ConfigServer) { const int configServerModeNumber = 2; @@ -420,8 +414,37 @@ public: return true; } + +protected: + CmdHello(const StringData cmdName, const std::initializer_list& alias) + : BasicCommand(cmdName, alias) {} + + virtual bool useLegacyResponseFields() { + return false; + } + } cmdhello; +class CmdIsMaster : public CmdHello { +public: + CmdIsMaster() : CmdHello(kCamelCaseIsMasterString, {kLowerCaseIsMasterString}) {} + + void help(stringstream& help) const override { + help << "Check if this server is primary for a replica pair/set; also if it is --master or " + "--slave in simple master/slave setups.\n"; + help << "{ isMaster : 1 }"; + } + +protected: + // Parse the command name, which should be one of the following: hello, isMaster, or + // ismaster. If the command is "hello", we must attach an "isWritablePrimary" response field + // instead of "ismaster" and "secondaryDelaySecs" response field instead of "slaveDelay". + bool useLegacyResponseFields() override { + return true; + } + +} cmdIsMaster; + OpCounterServerStatusSection replOpCounterServerStatusSection("opcountersRepl", &replOpCounters); } // namespace diff --git a/src/mongo/s/commands/cluster_is_master_cmd.cpp b/src/mongo/s/commands/cluster_is_master_cmd.cpp index e4876f7c1a7..1c950b5ecda 100644 --- a/src/mongo/s/commands/cluster_is_master_cmd.cpp +++ b/src/mongo/s/commands/cluster_is_master_cmd.cpp @@ -50,13 +50,12 @@ namespace mongo { namespace { constexpr auto kHelloString = "hello"_sd; -// Aliases for the hello command in order to provide backwards compatibility. constexpr auto kCamelCaseIsMasterString = "isMaster"_sd; constexpr auto kLowerCaseIsMasterString = "ismaster"_sd; class CmdHello : public BasicCommand { public: - CmdHello() : BasicCommand(kHelloString, {kCamelCaseIsMasterString, kLowerCaseIsMasterString}) {} + CmdHello() : CmdHello(kHelloString, {}) {} bool supportsWriteConcern(const BSONObj& cmd) const override { return false; @@ -84,11 +83,6 @@ public: const std::string& dbname, const BSONObj& cmdObj, BSONObjBuilder& result) override { - // Parse the command name, which should be one of the following: hello, isMaster, or - // ismaster. If the command is "hello", we must attach an "isWritablePrimary" response field - // instead of "ismaster". - bool useLegacyResponseFields = (cmdObj.firstElementFieldName() != kHelloString); - auto& clientMetadataIsMasterState = ClientMetadataIsMasterState::get(opCtx->getClient()); bool seenIsMaster = clientMetadataIsMasterState.hasSeenIsMaster(); if (!seenIsMaster) { @@ -123,7 +117,7 @@ public: opCtx->getClient(), std::move(swParseClientMetadata.getValue())); } - if (useLegacyResponseFields) { + if (useLegacyResponseFields()) { result.appendBool("ismaster", true); } else { result.appendBool("isWritablePrimary", true); @@ -156,7 +150,27 @@ public: return true; } +protected: + CmdHello(const StringData cmdName, const std::initializer_list& alias) + : BasicCommand(cmdName, alias) {} + + virtual bool useLegacyResponseFields() { + return false; + } + } hello; +class CmdIsMaster : public CmdHello { + +public: + CmdIsMaster() : CmdHello(kCamelCaseIsMasterString, {kLowerCaseIsMasterString}) {} + +protected: + bool useLegacyResponseFields() override { + return true; + } + +} isMaster; + } // namespace } // namespace mongo -- cgit v1.2.1