diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2018-02-26 17:02:55 -0500 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2018-03-01 07:40:54 -0500 |
commit | abc0f64403a170f2145e52f2ff28ccaf3b297b6f (patch) | |
tree | 385fd2371c473312493229af389d46131317d93e /src/mongo/s | |
parent | 74824705de288dc46a691a517e9c17e060b042e3 (diff) | |
download | mongo-abc0f64403a170f2145e52f2ff28ccaf3b297b6f.tar.gz |
SERVER-28684 Get rid of trivial usages of PublicGridCommand::passthrough
Removes the usage of 'passthrough' from the eval and validate commands.
Diffstat (limited to 'src/mongo/s')
-rw-r--r-- | src/mongo/s/commands/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_eval_cmd.cpp | 91 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_validate_cmd.cpp | 133 | ||||
-rw-r--r-- | src/mongo/s/commands/commands_public.cpp | 108 |
4 files changed, 226 insertions, 108 deletions
diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript index 01273cd120b..11765392956 100644 --- a/src/mongo/s/commands/SConscript +++ b/src/mongo/s/commands/SConscript @@ -41,6 +41,7 @@ env.Library( 'cluster_drop_database_cmd.cpp', 'cluster_drop_indexes_cmd.cpp', 'cluster_enable_sharding_cmd.cpp', + 'cluster_eval_cmd.cpp', 'cluster_explain.cpp', 'cluster_explain_cmd.cpp', 'cluster_find_and_modify_cmd.cpp', @@ -80,6 +81,7 @@ env.Library( 'cluster_split_cmd.cpp', 'cluster_update_zone_key_range_cmd.cpp', 'cluster_user_management_commands.cpp', + 'cluster_validate_cmd.cpp', 'cluster_whats_my_uri_cmd.cpp', 'cluster_write_cmd.cpp', 'commands_public.cpp', diff --git a/src/mongo/s/commands/cluster_eval_cmd.cpp b/src/mongo/s/commands/cluster_eval_cmd.cpp new file mode 100644 index 00000000000..b546a4f7dc4 --- /dev/null +++ b/src/mongo/s/commands/cluster_eval_cmd.cpp @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2015 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand + +#include "mongo/platform/basic.h" + +#include "mongo/db/auth/role_graph.h" +#include "mongo/db/commands.h" +#include "mongo/s/catalog_cache.h" +#include "mongo/s/grid.h" +#include "mongo/util/log.h" + +namespace mongo { +namespace { + +class EvalCmd : public BasicCommand { +public: + EvalCmd() : BasicCommand("eval", "$eval") {} + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kAlways; + } + + void addRequiredPrivileges(const std::string& dbName, + const BSONObj& cmdObj, + std::vector<Privilege>* out) const override { + // $eval can do pretty much anything, so require all privileges. + RoleGraph::generateUniversalPrivileges(out); + } + + bool supportsWriteConcern(const BSONObj& cmd) const override { + return false; + } + + bool run(OperationContext* opCtx, + const std::string& dbName, + const BSONObj& cmdObj, + BSONObjBuilder& result) override { + RARELY { + warning() << "the eval command is deprecated" << startupWarningsLog; + } + + // $eval isn't allowed to access sharded collections, but we need to leave the shard to + // detect that + const auto dbInfo = + uassertStatusOK(Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, dbName)); + auto shard = + uassertStatusOK(Grid::get(opCtx)->shardRegistry()->getShard(opCtx, dbInfo.primaryId())); + + auto commandResponse = uassertStatusOK( + shard->runCommand(opCtx, + ReadPreferenceSetting::get(opCtx), + dbName, + CommandHelpers::filterCommandRequestForPassthrough(cmdObj), + Shard::RetryPolicy::kNoRetry)); + + result.appendElementsUnique( + CommandHelpers::filterCommandReplyForPassthrough(commandResponse.response)); + return true; + } + +} evalCmd; + +} // namespace +} // namespace mongo diff --git a/src/mongo/s/commands/cluster_validate_cmd.cpp b/src/mongo/s/commands/cluster_validate_cmd.cpp new file mode 100644 index 00000000000..7a63e9a4327 --- /dev/null +++ b/src/mongo/s/commands/cluster_validate_cmd.cpp @@ -0,0 +1,133 @@ +/** + * Copyright (C) 2015 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand + +#include "mongo/platform/basic.h" + +#include "mongo/db/commands.h" +#include "mongo/rpc/get_status_from_command_result.h" +#include "mongo/s/commands/cluster_commands_helpers.h" + +namespace mongo { +namespace { + +class ValidateCmd : public BasicCommand { +public: + ValidateCmd() : BasicCommand("validate") {} + + std::string parseNs(const std::string& dbname, const BSONObj& cmdObj) const override { + return CommandHelpers::parseNsCollectionRequired(dbname, cmdObj).ns(); + } + + AllowedOnSecondary secondaryAllowed(ServiceContext*) const override { + return AllowedOnSecondary::kAlways; + } + + bool adminOnly() const override { + return false; + } + + void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector<Privilege>* out) const override { + ActionSet actions; + actions.addAction(ActionType::validate); + out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions)); + } + + bool supportsWriteConcern(const BSONObj& cmd) const override { + return false; + } + + bool run(OperationContext* opCtx, + const std::string& dbName, + const BSONObj& cmdObj, + BSONObjBuilder& output) override { + const NamespaceString nss(parseNs(dbName, cmdObj)); + + auto results = scatterGatherVersionedTargetByRoutingTable( + opCtx, + dbName, + nss, + CommandHelpers::filterCommandRequestForPassthrough(cmdObj), + ReadPreferenceSetting::get(opCtx), + Shard::RetryPolicy::kIdempotent, + {}, + {}); + + Status firstFailedShardStatus = Status::OK(); + bool isValid = true; + + BSONObjBuilder rawResBuilder(output.subobjStart("raw")); + for (const auto& cmdResult : results) { + const auto& shardId = cmdResult.shardId; + + const auto& swResponse = cmdResult.swResponse; + if (!swResponse.isOK()) { + rawResBuilder.append(shardId.toString(), + BSON("error" << swResponse.getStatus().toString())); + if (firstFailedShardStatus.isOK()) + firstFailedShardStatus = swResponse.getStatus(); + continue; + } + + const auto& response = swResponse.getValue(); + if (!response.isOK()) { + rawResBuilder.append(shardId.toString(), + BSON("error" << response.status.toString())); + if (firstFailedShardStatus.isOK()) + firstFailedShardStatus = response.status; + continue; + } + + rawResBuilder.append(shardId.toString(), response.data); + + const auto status = getStatusFromCommandResult(response.data); + if (!status.isOK()) { + if (firstFailedShardStatus.isOK()) + firstFailedShardStatus = status; + continue; + } + + if (!response.data["valid"].trueValue()) { + isValid = false; + } + } + rawResBuilder.done(); + + if (firstFailedShardStatus.isOK()) + output.appendBool("valid", isValid); + + return CommandHelpers::appendCommandStatus(output, firstFailedShardStatus); + } + +} validateCmd; + +} // namespace +} // namespace mongo diff --git a/src/mongo/s/commands/commands_public.cpp b/src/mongo/s/commands/commands_public.cpp index 7b13a0fa7e9..54499f66924 100644 --- a/src/mongo/s/commands/commands_public.cpp +++ b/src/mongo/s/commands/commands_public.cpp @@ -191,82 +191,6 @@ protected: } }; -class ValidateCmd : public PublicGridCommand { -public: - ValidateCmd() : PublicGridCommand("validate") {} - - void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) const override { - ActionSet actions; - actions.addAction(ActionType::validate); - out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions)); - } - - bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } - - bool run(OperationContext* opCtx, - const std::string& dbName, - const BSONObj& cmdObj, - BSONObjBuilder& output) override { - const NamespaceString nss(CommandHelpers::parseNsCollectionRequired(dbName, cmdObj)); - - auto routingInfo = - uassertStatusOK(Grid::get(opCtx)->catalogCache()->getCollectionRoutingInfo(opCtx, nss)); - if (!routingInfo.cm()) { - return passthrough(opCtx, dbName, routingInfo.primaryId(), cmdObj, output); - } - - const auto cm = routingInfo.cm(); - - std::vector<Strategy::CommandResult> results; - const BSONObj query; - Strategy::commandOp(opCtx, - dbName, - CommandHelpers::filterCommandRequestForPassthrough(cmdObj), - cm->getns().ns(), - query, - CollationSpec::kSimpleSpec, - &results); - - BSONObjBuilder rawResBuilder(output.subobjStart("raw")); - bool isValid = true; - bool errored = false; - for (const auto& cmdResult : results) { - const ShardId& shardName = cmdResult.shardTargetId; - BSONObj result = cmdResult.result; - const BSONElement valid = result["valid"]; - if (!valid.trueValue()) { - isValid = false; - } - if (!result["errmsg"].eoo()) { - // errmsg indicates a user error, so returning the message from one shard is - // sufficient. - output.append(result["errmsg"]); - errored = true; - } - rawResBuilder.append(shardName.toString(), result); - } - rawResBuilder.done(); - - output.appendBool("valid", isValid); - - int code = getUniqueCodeFromCommandResults(results); - if (code != 0) { - output.append("code", code); - output.append("codeName", ErrorCodes::errorString(ErrorCodes::Error(code))); - } - - if (errored) { - return false; - } - return true; - } - -} validateCmd; - class RenameCollectionCmd : public PublicGridCommand { public: RenameCollectionCmd() : PublicGridCommand("renameCollection") {} @@ -1089,38 +1013,6 @@ public: } geo2dFindNearCmd; -class EvalCmd : public PublicGridCommand { -public: - EvalCmd() : PublicGridCommand("eval", "$eval") {} - - void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) const override { - // $eval can do pretty much anything, so require all privileges. - RoleGraph::generateUniversalPrivileges(out); - } - - bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } - - bool run(OperationContext* opCtx, - const std::string& dbName, - const BSONObj& cmdObj, - BSONObjBuilder& result) override { - RARELY { - warning() << "the eval command is deprecated" << startupWarningsLog; - } - - // $eval isn't allowed to access sharded collections, but we need to leave the shard to - // detect that - const auto dbInfo = - uassertStatusOK(Grid::get(opCtx)->catalogCache()->getDatabase(opCtx, dbName)); - return passthrough(opCtx, dbName, dbInfo.primaryId(), cmdObj, result); - } - -} evalCmd; - class CmdListCollections : public BasicCommand { public: CmdListCollections() : BasicCommand("listCollections") {} |