summaryrefslogtreecommitdiff
path: root/src/mongo/s
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2018-02-26 17:02:55 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2018-03-01 07:40:54 -0500
commitabc0f64403a170f2145e52f2ff28ccaf3b297b6f (patch)
tree385fd2371c473312493229af389d46131317d93e /src/mongo/s
parent74824705de288dc46a691a517e9c17e060b042e3 (diff)
downloadmongo-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/SConscript2
-rw-r--r--src/mongo/s/commands/cluster_eval_cmd.cpp91
-rw-r--r--src/mongo/s/commands/cluster_validate_cmd.cpp133
-rw-r--r--src/mongo/s/commands/commands_public.cpp108
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") {}