summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2018-07-25 15:04:48 -0400
committerMathias Stearn <mathias@10gen.com>2018-07-30 13:57:10 -0400
commit480192de1789e8387b64976ad015c11fac990617 (patch)
tree1bd8c4bf54334ca55254bbf534ad3d7127843355
parentd68d672dd4cc27c92be897e7523fad85664fc39e (diff)
downloadmongo-480192de1789e8387b64976ad015c11fac990617.tar.gz
SERVER-33135 Delete code for OP_COMMAND
-rw-r--r--jstests/libs/profiler.js2
-rw-r--r--jstests/noPassthroughWithMongod/rpc_protocols.js36
-rw-r--r--src/mongo/client/dbclient_base.h2
-rw-r--r--src/mongo/client/dbclient_connection.cpp2
-rw-r--r--src/mongo/client/dbclient_cursor.cpp2
-rw-r--r--src/mongo/db/SConscript3
-rw-r--r--src/mongo/db/curop.cpp4
-rw-r--r--src/mongo/db/curop.h8
-rw-r--r--src/mongo/db/dbmessage.h2
-rw-r--r--src/mongo/db/service_entry_point_common.cpp4
-rw-r--r--src/mongo/dbtests/mock/mock_remote_db_server.cpp9
-rw-r--r--src/mongo/executor/network_interface.h2
-rw-r--r--src/mongo/rpc/SConscript40
-rw-r--r--src/mongo/rpc/command_reply.cpp99
-rw-r--r--src/mongo/rpc/command_reply.h83
-rw-r--r--src/mongo/rpc/command_reply_builder.cpp113
-rw-r--r--src/mongo/rpc/command_reply_builder.h91
-rw-r--r--src/mongo/rpc/command_reply_test.cpp143
-rw-r--r--src/mongo/rpc/command_request.cpp141
-rw-r--r--src/mongo/rpc/command_request.h55
-rw-r--r--src/mongo/rpc/command_request_builder.cpp105
-rw-r--r--src/mongo/rpc/command_request_builder.h40
-rw-r--r--src/mongo/rpc/command_request_builder_test.cpp97
-rw-r--r--src/mongo/rpc/command_request_test.cpp158
-rw-r--r--src/mongo/rpc/factory.cpp18
-rw-r--r--src/mongo/rpc/message.h42
-rw-r--r--src/mongo/rpc/metadata.h3
-rw-r--r--src/mongo/rpc/metadata/client_metadata.h2
-rw-r--r--src/mongo/rpc/metadata/client_metadata_ismaster.h6
-rw-r--r--src/mongo/rpc/protocol.cpp37
-rw-r--r--src/mongo/rpc/protocol.h10
-rw-r--r--src/mongo/rpc/protocol_test.cpp13
-rw-r--r--src/mongo/rpc/reply_builder_test.cpp26
-rw-r--r--src/mongo/s/service_entry_point_mongos.cpp1
-rw-r--r--src/mongo/shell/shell_options.cpp5
-rw-r--r--src/mongo/tools/bridge.cpp7
-rw-r--r--src/mongo/transport/SConscript3
37 files changed, 84 insertions, 1330 deletions
diff --git a/jstests/libs/profiler.js b/jstests/libs/profiler.js
index 6fe2c841cee..63af457299b 100644
--- a/jstests/libs/profiler.js
+++ b/jstests/libs/profiler.js
@@ -57,8 +57,6 @@ function getProfilerProtocolStringForCommand(conn) {
const protocols = conn.getClientRPCProtocols();
if ("all" === protocols || /Msg/.test(protocols))
return "op_msg";
- if (/Command/.test(protocols))
- return "op_command";
if (/Query/.test(protocols))
return "op_query";
doassert(`Unknown prototocol string ${protocols}`);
diff --git a/jstests/noPassthroughWithMongod/rpc_protocols.js b/jstests/noPassthroughWithMongod/rpc_protocols.js
index 4a5e436454b..ef847e2a359 100644
--- a/jstests/noPassthroughWithMongod/rpc_protocols.js
+++ b/jstests/noPassthroughWithMongod/rpc_protocols.js
@@ -1,11 +1,11 @@
// Regression test for SERVER-21673.
-// A user can configure the shell to send commands via OP_QUERY or OP_COMMAND. This can be done at
+// A user can configure the shell to send commands via OP_QUERY or OP_MSG. This can be done at
// startup using the "--rpcProtocols" command line option, or at runtime using the
// "setClientRPCProtocols" method on the Mongo object.
// @tags: [requires_profiling]
-var RPC_PROTOCOLS = {OP_QUERY: "opQueryOnly", OP_COMMAND: "opCommandOnly"};
+var RPC_PROTOCOLS = {OP_QUERY: "opQueryOnly", OP_MSG: "opMsgOnly"};
(function() {
"use strict";
@@ -34,19 +34,19 @@ var RPC_PROTOCOLS = {OP_QUERY: "opQueryOnly", OP_COMMAND: "opCommandOnly"};
assert(profileDoc !== null);
assert.eq(profileDoc.protocol, "op_query");
- // Test that --rpcProtocols=opCommandOnly forces OP_COMMAND commands.
- runInShell(RPC_PROTOCOLS.OP_COMMAND, function() {
- assert(db.getMongo().getClientRPCProtocols() === "opCommandOnly");
- db.getSiblingDB("test").rpcProtocols.find().comment("opCommandCommandLine").itcount();
+ // Test that --rpcProtocols=opMsgOnly forces OP_MSG commands.
+ runInShell(RPC_PROTOCOLS.OP_MSG, function() {
+ assert(db.getMongo().getClientRPCProtocols() === "opMsgOnly");
+ db.getSiblingDB("test").rpcProtocols.find().comment("opMsgCommandLine").itcount();
});
- profileDoc = db.system.profile.findOne({"command.comment": "opCommandCommandLine"});
+ profileDoc = db.system.profile.findOne({"command.comment": "opMsgCommandLine"});
assert(profileDoc !== null);
- assert.eq(profileDoc.protocol, "op_command");
+ assert.eq(profileDoc.protocol, "op_msg");
// Test that .setClientRPCProtocols("opQueryOnly") forces OP_QUERY commands. We start the shell
- // in OP_COMMAND only mode, then switch it to OP_QUERY mode at runtime.
- runInShell(RPC_PROTOCOLS.OP_COMMAND, function() {
- assert(db.getMongo().getClientRPCProtocols() === "opCommandOnly");
+ // in OP_MSG only mode, then switch it to OP_QUERY mode at runtime.
+ runInShell(RPC_PROTOCOLS.OP_MSG, function() {
+ assert(db.getMongo().getClientRPCProtocols() === "opMsgOnly");
db.getMongo().setClientRPCProtocols("opQueryOnly");
assert(db.getMongo().getClientRPCProtocols() === "opQueryOnly");
db.getSiblingDB("test").rpcProtocols.find().comment("opQueryRuntime").itcount();
@@ -55,17 +55,17 @@ var RPC_PROTOCOLS = {OP_QUERY: "opQueryOnly", OP_COMMAND: "opCommandOnly"};
assert(profileDoc !== null);
assert.eq(profileDoc.protocol, "op_query");
- // Test that .setClientRPCProtocols("opCommandOnly") forces OP_COMMAND commands. We start the
- // shell in OP_QUERY only mode, then switch it to OP_COMMAND mode at runtime.
+ // Test that .setClientRPCProtocols("opMsgOnly") forces OP_MSG commands. We start the
+ // shell in OP_QUERY only mode, then switch it to OP_MSG mode at runtime.
runInShell(RPC_PROTOCOLS.OP_QUERY, function() {
assert(db.getMongo().getClientRPCProtocols() === "opQueryOnly");
- db.getMongo().setClientRPCProtocols("opCommandOnly");
- assert(db.getMongo().getClientRPCProtocols() === "opCommandOnly");
- db.getSiblingDB("test").rpcProtocols.find().comment("opCommandRuntime").itcount();
+ db.getMongo().setClientRPCProtocols("opMsgOnly");
+ assert(db.getMongo().getClientRPCProtocols() === "opMsgOnly");
+ db.getSiblingDB("test").rpcProtocols.find().comment("opMsgRuntime").itcount();
});
- profileDoc = db.system.profile.findOne({"command.comment": "opCommandRuntime"});
+ profileDoc = db.system.profile.findOne({"command.comment": "opMsgRuntime"});
assert(profileDoc !== null);
- assert.eq(profileDoc.protocol, "op_command");
+ assert.eq(profileDoc.protocol, "op_msg");
// Reset profiling level.
assert.commandWorked(db.setProfilingLevel(oldProfilingLevel));
diff --git a/src/mongo/client/dbclient_base.h b/src/mongo/client/dbclient_base.h
index 141f41f880d..7ce43ba657b 100644
--- a/src/mongo/client/dbclient_base.h
+++ b/src/mongo/client/dbclient_base.h
@@ -702,7 +702,7 @@ private:
/**
* The rpc protocol the remote server(s) support. We support 'opQueryOnly' by default unless
- * we detect support for OP_COMMAND at connection time.
+ * we detect support for OP_MSG at connection time.
*/
rpc::ProtocolSet _serverRPCProtocols{rpc::supports::kOpQueryOnly};
diff --git a/src/mongo/client/dbclient_connection.cpp b/src/mongo/client/dbclient_connection.cpp
index dbabb5ebc82..d0940a873e4 100644
--- a/src/mongo/client/dbclient_connection.cpp
+++ b/src/mongo/client/dbclient_connection.cpp
@@ -109,7 +109,7 @@ executor::RemoteCommandResponse initWireVersion(DBClientConnection* conn,
StringData applicationName) {
try {
// We need to force the usage of OP_QUERY on this command, even if we have previously
- // detected support for OP_COMMAND on a connection. This is necessary to handle the case
+ // detected support for OP_MSG on a connection. This is necessary to handle the case
// where we reconnect to an older version of MongoDB running at the same host/port.
ScopedForceOpQuery forceOpQuery{conn};
diff --git a/src/mongo/client/dbclient_cursor.cpp b/src/mongo/client/dbclient_cursor.cpp
index bafdfea1990..321d19d0eef 100644
--- a/src/mongo/client/dbclient_cursor.cpp
+++ b/src/mongo/client/dbclient_cursor.cpp
@@ -247,7 +247,7 @@ void DBClientCursor::exhaustReceiveMore() {
BSONObj DBClientCursor::commandDataReceived(const Message& reply) {
int op = reply.operation();
- invariant(op == opReply || op == dbCommandReply || op == dbMsg);
+ invariant(op == opReply || op == dbMsg);
auto commandReply = _client->parseCommandReplyMessage(_client->getServerAddress(), reply);
auto commandStatus = getStatusFromCommandResult(commandReply->getCommandReply());
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index b792d074862..a33f95db62f 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -442,8 +442,7 @@ env.Library(
LIBDEPS=[
"$BUILD_DIR/mongo/client/clientdriver_network",
"$BUILD_DIR/mongo/db/auth/auth",
- "$BUILD_DIR/mongo/rpc/command_reply",
- "$BUILD_DIR/mongo/rpc/command_request",
+ "$BUILD_DIR/mongo/rpc/rpc",
"$BUILD_DIR/mongo/rpc/metadata",
"$BUILD_DIR/mongo/util/processinfo",
"$BUILD_DIR/mongo/util/signal_handlers",
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp
index e6bc3462528..edd98dc2b99 100644
--- a/src/mongo/db/curop.cpp
+++ b/src/mongo/db/curop.cpp
@@ -285,7 +285,7 @@ void CurOp::setGenericOpRequestDetails(OperationContext* opCtx,
// Set the _isCommand flags based on network op only. For legacy writes on mongoS, we resolve
// them to OpMsgRequests and then pass them into the Commands path, so having a valid Command*
// here does not guarantee that the op was issued from the client using a command protocol.
- const bool isCommand = (op == dbMsg || op == dbCommand || (op == dbQuery && nss.isCommand()));
+ const bool isCommand = (op == dbMsg || (op == dbQuery && nss.isCommand()));
auto logicalOp = (command ? command->getLogicalOp() : networkOpToLogicalOp(op));
stdx::lock_guard<Client> clientLock(*opCtx->getClient());
@@ -478,8 +478,6 @@ StringData getProtoString(int op) {
return "op_msg";
} else if (op == dbQuery) {
return "op_query";
- } else if (op == dbCommand) {
- return "op_command";
}
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h
index 52b03ac7db2..4782935f8bf 100644
--- a/src/mongo/db/curop.h
+++ b/src/mongo/db/curop.h
@@ -150,10 +150,10 @@ public:
// -------------------
// basic options
- // _networkOp represents the network-level op code: OP_QUERY, OP_GET_MORE, OP_COMMAND, etc.
+ // _networkOp represents the network-level op code: OP_QUERY, OP_GET_MORE, OP_MSG, etc.
NetworkOp networkOp{opInvalid}; // only set this through setNetworkOp_inlock() to keep synced
// _logicalOp is the logical operation type, ie 'dbQuery' regardless of whether this is an
- // OP_QUERY find, a find command using OP_QUERY, or a find command using OP_COMMAND.
+ // OP_QUERY find, a find command using OP_QUERY, or a find command using OP_MSG.
// Similarly, the return value will be dbGetMore for both OP_GET_MORE and getMore command.
LogicalOp logicalOp{LogicalOp::opInvalid}; // only set this through setNetworkOp_inlock()
bool iscommand{false};
@@ -578,10 +578,10 @@ private:
// The cumulative duration for which the timer has been paused.
Microseconds _totalPausedDuration{0};
- // _networkOp represents the network-level op code: OP_QUERY, OP_GET_MORE, OP_COMMAND, etc.
+ // _networkOp represents the network-level op code: OP_QUERY, OP_GET_MORE, OP_MSG, etc.
NetworkOp _networkOp{opInvalid}; // only set this through setNetworkOp_inlock() to keep synced
// _logicalOp is the logical operation type, ie 'dbQuery' regardless of whether this is an
- // OP_QUERY find, a find command using OP_QUERY, or a find command using OP_COMMAND.
+ // OP_QUERY find, a find command using OP_QUERY, or a find command using OP_MSG.
// Similarly, the return value will be dbGetMore for both OP_GET_MORE and getMore command.
LogicalOp _logicalOp{LogicalOp::opInvalid}; // only set this through setNetworkOp_inlock()
diff --git a/src/mongo/db/dbmessage.h b/src/mongo/db/dbmessage.h
index e545130e7ed..f3e711bfae8 100644
--- a/src/mongo/db/dbmessage.h
+++ b/src/mongo/db/dbmessage.h
@@ -450,7 +450,7 @@ struct DbResponse {
/**
* Prepares query replies to legacy finds (opReply to dbQuery) in place. This is also used for
- * command responses that don't use the new dbCommand protocol.
+ * command responses that don't use the new dbMsg protocol.
*/
class OpQueryReplyBuilder {
MONGO_DISALLOW_COPYING(OpQueryReplyBuilder);
diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp
index ac6d691418b..16a4671961f 100644
--- a/src/mongo/db/service_entry_point_common.cpp
+++ b/src/mongo/db/service_entry_point_common.cpp
@@ -1297,7 +1297,7 @@ DbResponse ServiceEntryPointCommon::handleRequest(OperationContext* opCtx,
if (nsString.isCommand()) {
isCommand = true;
}
- } else if (op == dbCommand || op == dbMsg) {
+ } else if (op == dbMsg) {
isCommand = true;
}
@@ -1316,7 +1316,7 @@ DbResponse ServiceEntryPointCommon::handleRequest(OperationContext* opCtx,
bool forceLog = false;
DbResponse dbresponse;
- if (op == dbMsg || op == dbCommand || (op == dbQuery && isCommand)) {
+ if (op == dbMsg || (op == dbQuery && isCommand)) {
dbresponse = receivedCommands(opCtx, m, behaviors);
} else if (op == dbQuery) {
invariant(!isCommand);
diff --git a/src/mongo/dbtests/mock/mock_remote_db_server.cpp b/src/mongo/dbtests/mock/mock_remote_db_server.cpp
index 0d09a1036c6..0c18b18bfb1 100644
--- a/src/mongo/dbtests/mock/mock_remote_db_server.cpp
+++ b/src/mongo/dbtests/mock/mock_remote_db_server.cpp
@@ -32,9 +32,8 @@
#include <tuple>
#include "mongo/dbtests/mock/mock_dbclient_connection.h"
-#include "mongo/rpc/command_reply.h"
-#include "mongo/rpc/command_reply_builder.h"
#include "mongo/rpc/metadata.h"
+#include "mongo/rpc/op_msg_rpc_impls.h"
#include "mongo/stdx/memory.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/mongoutils/str.h"
@@ -163,12 +162,12 @@ rpc::UniqueReply MockRemoteDBServer::runCommand(InstanceID id, const OpMsgReques
}
// We need to construct a reply message - it will always be read through a view so it
- // doesn't matter whether we use CommandReplBuilder or LegacyReplyBuilder
- auto message = rpc::CommandReplyBuilder{}
+ // doesn't matter whether we use OpMsgReplyBuilder or LegacyReplyBuilder
+ auto message = rpc::OpMsgReplyBuilder{}
.setCommandReply(reply)
.setMetadata(rpc::makeEmptyMetadata())
.done();
- auto replyView = stdx::make_unique<rpc::CommandReply>(&message);
+ auto replyView = stdx::make_unique<rpc::OpMsgReply>(&message);
return rpc::UniqueReply(std::move(message), std::move(replyView));
}
diff --git a/src/mongo/executor/network_interface.h b/src/mongo/executor/network_interface.h
index dc3a089626e..f76adbfe35b 100644
--- a/src/mongo/executor/network_interface.h
+++ b/src/mongo/executor/network_interface.h
@@ -135,7 +135,7 @@ public:
/**
* Starts asynchronous execution of the command described by "request".
*
- * The request mutated to append request metadata to be sent in OP_Command messages.
+ * The request mutated to append request metadata to be merged into the request messages.
*
* Returns ErrorCodes::ShutdownInProgress if NetworkInterface::shutdown has already started
* and Status::OK() otherwise. If it returns Status::OK(), then the onFinish argument will be
diff --git a/src/mongo/rpc/SConscript b/src/mongo/rpc/SConscript
index fff0a749384..95769004eb1 100644
--- a/src/mongo/rpc/SConscript
+++ b/src/mongo/rpc/SConscript
@@ -47,8 +47,6 @@ env.Library(
'factory.cpp',
],
LIBDEPS=[
- 'command_reply',
- 'command_request',
'legacy_reply',
'legacy_request',
'metadata',
@@ -73,21 +71,6 @@ env.Library(
env.Library(
target=[
- 'command_request',
- ],
- source=[
- 'command_request.cpp',
- 'command_request_builder.cpp',
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/client/read_preference',
- '$BUILD_DIR/mongo/db/server_options_core',
- '$BUILD_DIR/mongo/util/net/network',
- ],
-)
-
-env.Library(
- target=[
'legacy_request',
],
source=[
@@ -103,31 +86,17 @@ env.Library(
env.Library(
target=[
- 'command_reply',
- ],
- source=[
- 'command_reply.cpp',
- 'command_reply_builder.cpp',
- 'reply_builder_interface.cpp',
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/db/server_options_core',
- '$BUILD_DIR/mongo/util/net/network',
- ],
-)
-
-env.Library(
- target=[
'legacy_reply',
],
source=[
'legacy_reply.cpp',
- 'legacy_reply_builder.cpp'
+ 'legacy_reply_builder.cpp',
+ 'reply_builder_interface.cpp',
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/server_options_core',
'$BUILD_DIR/mongo/s/common_s',
'$BUILD_DIR/mongo/util/net/network',
- 'command_reply',
'metadata',
'object_check',
],
@@ -197,9 +166,6 @@ env.CppUnitTest(
'rpc_test',
],
source=[
- 'command_reply_test.cpp',
- 'command_request_builder_test.cpp',
- 'command_request_test.cpp',
'get_status_from_command_result_test.cpp',
'legacy_request_test.cpp',
'object_check_test.cpp',
diff --git a/src/mongo/rpc/command_reply.cpp b/src/mongo/rpc/command_reply.cpp
deleted file mode 100644
index 79de0cc5506..00000000000
--- a/src/mongo/rpc/command_reply.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * 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.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/rpc/command_reply.h"
-
-#include <tuple>
-#include <utility>
-
-#include "mongo/base/data_range_cursor.h"
-#include "mongo/base/data_type_validated.h"
-#include "mongo/bson/simple_bsonobj_comparator.h"
-#include "mongo/rpc/message.h"
-#include "mongo/rpc/object_check.h"
-
-namespace mongo {
-namespace rpc {
-
-CommandReply::CommandReply(const Message* message) : _message(message) {
- const char* begin = _message->singleData().data();
- std::size_t length = _message->singleData().dataLen();
-
- // This check failing would normally be operation fatal, but we expect it to have been
- // done earlier in the network layer, so we make it an invariant.
- invariant(length <= MaxMessageSizeBytes);
-
- const char* messageEnd = begin + length;
- ConstDataRangeCursor cur(begin, messageEnd);
-
- _commandReply = uassertStatusOK(cur.readAndAdvance<Validated<BSONObj>>()).val;
- _commandReply.shareOwnershipWith(message->sharedBuffer());
-
- // OP_COMMAND is only used when communicating with 3.4 nodes and they serialize their metadata
- // fields differently. We do all up- and down-conversion here so that the rest of the code only
- // has to deal with the current format.
- auto rawMetadata = uassertStatusOK(cur.readAndAdvance<Validated<BSONObj>>()).val;
- BSONObjBuilder metadataBuilder;
- for (auto elem : rawMetadata) {
- if (elem.fieldNameStringData() == "configsvr") {
- metadataBuilder.appendAs(elem, "$configServerState");
- } else {
- metadataBuilder.append(elem);
- }
- }
- _metadata = metadataBuilder.obj();
-
- uassert(40420, "OP_COMMAND reply contains trailing bytes following metadata", cur.empty());
-}
-
-const BSONObj& CommandReply::getMetadata() const {
- return _metadata;
-}
-
-const BSONObj& CommandReply::getCommandReply() const {
- return _commandReply;
-}
-
-Protocol CommandReply::getProtocol() const {
- return rpc::Protocol::kOpCommandV1;
-}
-
-bool operator==(const CommandReply& lhs, const CommandReply& rhs) {
- SimpleBSONObjComparator bsonComparator;
- return bsonComparator.evaluate(lhs._metadata == rhs._metadata) &&
- bsonComparator.evaluate(lhs._commandReply == rhs._commandReply);
-}
-
-bool operator!=(const CommandReply& lhs, const CommandReply& rhs) {
- return !(lhs == rhs);
-}
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/command_reply.h b/src/mongo/rpc/command_reply.h
deleted file mode 100644
index e1fb849f063..00000000000
--- a/src/mongo/rpc/command_reply.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * 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.
- */
-
-#pragma once
-
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/reply_interface.h"
-
-namespace mongo {
-class Message;
-
-namespace rpc {
-
-/**
- * An immutable view of an OP_COMMANDREPLY message. The underlying bytes are owned
- * by a mongo::Message, which must outlive any Reply instances created from it.
- *
- * TODO: _metadata and _commandReply are owned by the underlying message. When
- * we implement a BSONObjView or similar, we should use that here to make these semantics
- * explicit.
- * See SERVER-16730 for additional details.
- */
-class CommandReply : public ReplyInterface {
-public:
- /**
- * Construct a Reply from a Message.
- * The underlying message MUST outlive the Reply.
- * Required fields are parsed eagerly, outputDocs are parsed lazily.
- *
- * The underlying Message also handles the wire-protocol header.
- */
- explicit CommandReply(const Message* message);
-
- /**
- * Accessor for the metadata object. Metadata is generally used for information
- * that is independent of any specific command, e.g. auditing information.
- */
- const BSONObj& getMetadata() const final;
-
- /**
- * The result of executing the command.
- */
- const BSONObj& getCommandReply() const final;
-
- Protocol getProtocol() const final;
-
- friend bool operator==(const CommandReply& lhs, const CommandReply& rhs);
- friend bool operator!=(const CommandReply& lhs, const CommandReply& rhs);
-
-private:
- const Message* _message;
-
- BSONObj _metadata;
- BSONObj _commandReply;
-};
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/command_reply_builder.cpp b/src/mongo/rpc/command_reply_builder.cpp
deleted file mode 100644
index ba62df3e72e..00000000000
--- a/src/mongo/rpc/command_reply_builder.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * 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.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/rpc/command_reply_builder.h"
-
-#include <utility>
-
-#include "mongo/rpc/message.h"
-#include "mongo/stdx/memory.h"
-#include "mongo/util/assert_util.h"
-#include "mongo/util/mongoutils/str.h"
-
-namespace mongo {
-namespace rpc {
-
-CommandReplyBuilder::CommandReplyBuilder() : CommandReplyBuilder(Message{}) {}
-
-CommandReplyBuilder::CommandReplyBuilder(Message&& message) : _message{std::move(message)} {
- _builder.skip(mongo::MsgData::MsgDataHeaderSize);
-}
-
-CommandReplyBuilder& CommandReplyBuilder::setRawCommandReply(const BSONObj& commandReply) {
- invariant(_state == State::kCommandReply);
- commandReply.appendSelfToBufBuilder(_builder);
- _state = State::kMetadata;
- return *this;
-}
-
-BSONObjBuilder CommandReplyBuilder::getBodyBuilder() {
- if (_state == State::kMetadata) {
- invariant(_bodyOffset);
- return BSONObjBuilder(BSONObjBuilder::ResumeBuildingTag{}, _builder, _bodyOffset);
- }
- invariant(_state == State::kCommandReply);
- _state = State::kMetadata;
- auto bob = BSONObjBuilder(_builder);
- _bodyOffset = bob.offset();
- return bob;
-}
-
-CommandReplyBuilder& CommandReplyBuilder::setMetadata(const BSONObj& metadata) {
- invariant(_state == State::kMetadata);
- // OP_COMMAND is only used when communicating with 3.4 nodes and they serialize their metadata
- // fields differently. We do all up- and down-conversion here so that the rest of the code only
- // has to deal with the current format.
- BSONObjBuilder bob(_builder);
- for (auto elem : metadata) {
- if (elem.fieldNameStringData() == "$configServerState") {
- bob.appendAs(elem, "configsvr");
- } else {
- bob.append(elem);
- }
- }
- _state = State::kOutputDocs;
- return *this;
-}
-
-Protocol CommandReplyBuilder::getProtocol() const {
- return rpc::Protocol::kOpCommandV1;
-}
-
-void CommandReplyBuilder::reset() {
- // If we are in State::kCommandReply, we are already in the 'start' state, so by
- // immediately returning, we save a heap allocation.
- if (_state == State::kCommandReply) {
- return;
- }
- _builder.reset();
- _builder.skip(mongo::MsgData::MsgDataHeaderSize);
- _message.reset();
- _state = State::kCommandReply;
- _bodyOffset = 0;
-}
-
-Message CommandReplyBuilder::done() {
- invariant(_state == State::kOutputDocs);
- MsgData::View msg = _builder.buf();
- msg.setLen(_builder.len());
- msg.setOperation(dbCommandReply);
- _message.setData(_builder.release());
- _state = State::kDone;
- return std::move(_message);
-}
-
-} // rpc
-} // mongo
diff --git a/src/mongo/rpc/command_reply_builder.h b/src/mongo/rpc/command_reply_builder.h
deleted file mode 100644
index d3d741d678f..00000000000
--- a/src/mongo/rpc/command_reply_builder.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * 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.
- */
-
-#pragma once
-
-#include <memory>
-
-#include "mongo/base/status.h"
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/message.h"
-#include "mongo/rpc/protocol.h"
-#include "mongo/rpc/reply_builder_interface.h"
-
-namespace mongo {
-namespace rpc {
-
-/**
- * Constructs an OP_COMMANDREPLY message.
- */
-class CommandReplyBuilder : public ReplyBuilderInterface {
-public:
- /**
- * Constructs an OP_COMMANDREPLY in a new buffer.
- */
- CommandReplyBuilder();
-
- /*
- * Constructs an OP_COMMANDREPLY in an existing buffer. Ownership of the buffer
- * will be transfered to the CommandReplyBuilder.
- */
- CommandReplyBuilder(Message&& message);
-
-
- CommandReplyBuilder& setRawCommandReply(const BSONObj& commandReply) final;
- BSONObjBuilder getBodyBuilder() final;
-
- CommandReplyBuilder& setMetadata(const BSONObj& metadata) final;
-
- Protocol getProtocol() const final;
-
- void reset() final;
-
- /**
- * Writes data then transfers ownership of the message to the caller.
- * The behavior of calling any methods on the object is subsequently
- * undefined.
- */
- Message done() final;
-
- void reserveBytes(const std::size_t bytes) final {
- _builder.reserveBytes(bytes);
- _builder.claimReservedBytes(bytes);
- }
-
-private:
- enum class State { kMetadata, kCommandReply, kOutputDocs, kDone };
-
- // Default values are all empty.
- std::size_t _bodyOffset = 0;
- BufBuilder _builder{};
- Message _message;
- State _state{State::kCommandReply};
-};
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/command_reply_test.cpp b/src/mongo/rpc/command_reply_test.cpp
deleted file mode 100644
index e207c497b2b..00000000000
--- a/src/mongo/rpc/command_reply_test.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/**
- * 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.
- */
-
-#include "mongo/platform/basic.h"
-
-#include <cstdint>
-#include <iterator>
-#include <string>
-#include <vector>
-
-#include "mongo/base/data_type_endian.h"
-#include "mongo/base/data_view.h"
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/command_reply.h"
-#include "mongo/rpc/message.h"
-#include "mongo/stdx/memory.h"
-#include "mongo/unittest/unittest.h"
-
-namespace {
-
-using namespace mongo;
-
-using std::begin;
-using std::end;
-
-class ReplyTest : public mongo::unittest::Test {
-protected:
- std::vector<char> _cmdData{};
- Message _message{};
-
- virtual void setUp() override {
- _message.reset();
- }
-
- virtual void tearDown() override {
- _cmdData.clear();
- }
-
- void writeObj(const BSONObj& obj) {
- _cmdData.insert(end(_cmdData), obj.objdata(), obj.objdata() + obj.objsize());
- }
-
- void writeObj(const BSONObj& obj, std::size_t length) {
- _cmdData.insert(end(_cmdData), obj.objdata(), obj.objdata() + length);
- }
-
- const Message* buildMessage() {
- _cmdData.shrink_to_fit();
- _message.setData(dbCommandReply, _cmdData.data(), _cmdData.size());
- return &_message;
- }
-};
-
-TEST_F(ReplyTest, ParseAllFields) {
- BSONObjBuilder commandReplyBob{};
- commandReplyBob.append("baz", "garply");
- auto commandReply = commandReplyBob.done();
- writeObj(commandReply);
-
- BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
- auto metadata = metadataBob.done();
- writeObj(metadata);
-
- rpc::CommandReply opCmdReply{buildMessage()};
-
- ASSERT_BSONOBJ_EQ(opCmdReply.getMetadata(), metadata);
- ASSERT_BSONOBJ_EQ(opCmdReply.getCommandReply(), commandReply);
-}
-
-TEST_F(ReplyTest, EmptyMessageThrows) {
- ASSERT_THROWS(rpc::CommandReply{buildMessage()}, AssertionException);
-}
-
-TEST_F(ReplyTest, MetadataOnlyThrows) {
- BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
- auto metadata = metadataBob.done();
- writeObj(metadata);
-
- ASSERT_THROWS(rpc::CommandReply{buildMessage()}, AssertionException);
-}
-
-TEST_F(ReplyTest, MetadataInvalidLengthThrows) {
- BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
- auto metadata = metadataBob.done();
- auto trueSize = metadata.objsize();
- // write a super long length field
- DataView(const_cast<char*>(metadata.objdata())).write<LittleEndian<int32_t>>(100000);
- writeObj(metadata, trueSize);
- // write a valid commandReply
- BSONObjBuilder commandReplyBob{};
- commandReplyBob.append("baz", "garply");
- auto commandReply = commandReplyBob.done();
- writeObj(commandReply);
-
- ASSERT_THROWS(rpc::CommandReply{buildMessage()}, AssertionException);
-}
-
-TEST_F(ReplyTest, InvalidLengthThrows) {
- BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
- auto metadata = metadataBob.done();
- // write a valid metadata object
- writeObj(metadata);
-
- BSONObjBuilder commandReplyBob{};
- commandReplyBob.append("baz", "garply");
- auto commandReply = commandReplyBob.done();
- auto trueSize = commandReply.objsize();
- // write a super long length field
- DataView(const_cast<char*>(commandReply.objdata())).write<LittleEndian<int32_t>>(100000);
- writeObj(commandReply, trueSize);
-
- ASSERT_THROWS(rpc::CommandReply{buildMessage()}, AssertionException);
-}
-}
diff --git a/src/mongo/rpc/command_request.cpp b/src/mongo/rpc/command_request.cpp
deleted file mode 100644
index bce2323bfe5..00000000000
--- a/src/mongo/rpc/command_request.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * 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.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/rpc/command_request.h"
-
-#include <string>
-#include <utility>
-
-#include "mongo/base/data_range_cursor.h"
-#include "mongo/base/data_type.h"
-#include "mongo/base/data_type_terminated.h"
-#include "mongo/base/data_type_validated.h"
-#include "mongo/bson/simple_bsonobj_comparator.h"
-#include "mongo/client/read_preference.h"
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/message.h"
-#include "mongo/rpc/object_check.h"
-#include "mongo/util/assert_util.h"
-#include "mongo/util/mongoutils/str.h"
-
-namespace mongo {
-namespace rpc {
-
-namespace {
-// None of these include null byte
-const std::size_t kMinCommandNameLength = 1;
-const std::size_t kMaxCommandNameLength = 128;
-
-} // namespace
-
-ParsedOpCommand ParsedOpCommand::parse(const Message& message) {
- ParsedOpCommand out;
-
- char* begin = message.singleData().data();
- std::size_t length = message.singleData().dataLen();
-
- // checked in message_port.cpp
- invariant(length <= MaxMessageSizeBytes);
-
- const char* messageEnd = begin + length;
-
- ConstDataRangeCursor cur(begin, messageEnd);
-
- Terminated<'\0', StringData> str;
- uassertStatusOK(cur.readAndAdvance<>(&str));
- out.database = str.value.toString();
-
- uassertStatusOK(cur.readAndAdvance<>(&str));
- const auto commandName = std::move(str.value);
-
- uassert(28637,
- str::stream() << "Command name parsed in OP_COMMAND message must be between "
- << kMinCommandNameLength
- << " and "
- << kMaxCommandNameLength
- << " bytes. Got: "
- << out.database,
- (commandName.size() >= kMinCommandNameLength) &&
- (commandName.size() <= kMaxCommandNameLength));
-
- Validated<BSONObj> obj;
- uassertStatusOK(cur.readAndAdvance<>(&obj));
- out.body = std::move(obj.val);
- uassert(39950,
- str::stream() << "Command name parsed in OP_COMMAND message '" << commandName
- << "' doesn't match command name from object '"
- << out.body.firstElementFieldName()
- << '\'',
- out.body.firstElementFieldName() == commandName);
-
- uassertStatusOK(cur.readAndAdvance<>(&obj));
- out.metadata = std::move(obj.val);
-
- uassert(40419, "OP_COMMAND request contains trailing bytes following metadata", cur.empty());
-
- return out;
-}
-
-OpMsgRequest opMsgRequestFromCommandRequest(const Message& message) {
- auto parsed = ParsedOpCommand::parse(message);
-
- BSONObjBuilder bodyBuilder(std::move(parsed.body));
-
- // OP_COMMAND is only used when communicating with 3.4 nodes and they serialize their metadata
- // fields differently. We do all up-conversion here so that the rest of the code only has to
- // deal with the current format.
- for (auto elem : parsed.metadata) {
- if (elem.fieldNameStringData() == "configsvr") {
- bodyBuilder.appendAs(elem, "$configServerState");
- } else if (elem.fieldNameStringData() == "$ssm") {
- auto ssmObj = elem.Obj();
- if (auto readPrefElem = ssmObj["$readPreference"]) {
- // Promote the read preference to the top level.
- bodyBuilder.append(readPrefElem);
- } else if (ssmObj["$secondaryOk"].trueValue()) {
- // Convert secondaryOk to equivalent read preference if none was explicitly
- // provided.
- ReadPreferenceSetting(ReadPreference::SecondaryPreferred)
- .toContainingBSON(&bodyBuilder);
- }
- } else {
- bodyBuilder.append(elem);
- }
- }
-
- bodyBuilder.append("$db", parsed.database);
-
- OpMsgRequest request;
- request.body = bodyBuilder.obj();
- return request;
-}
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/command_request.h b/src/mongo/rpc/command_request.h
deleted file mode 100644
index d2163185422..00000000000
--- a/src/mongo/rpc/command_request.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * 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.
- */
-
-#pragma once
-
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/message.h"
-#include "mongo/rpc/op_msg.h"
-
-namespace mongo {
-namespace rpc {
-
-/**
- * This captures a full OP_COMMAND message before the body and metadata are merged. It should only
- * be used for testing and implementation of opMsgRequestFromCommandRequest(). All other code should
- * just use the general OpMsgRequest.
- */
-struct ParsedOpCommand {
- static ParsedOpCommand parse(const Message& message);
-
- std::string database;
- BSONObj body;
- BSONObj metadata;
-};
-
-
-OpMsgRequest opMsgRequestFromCommandRequest(const Message& message);
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/command_request_builder.cpp b/src/mongo/rpc/command_request_builder.cpp
deleted file mode 100644
index 68b39a460de..00000000000
--- a/src/mongo/rpc/command_request_builder.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * 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.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/rpc/command_request_builder.h"
-
-#include "mongo/client/read_preference.h"
-#include "mongo/db/command_generic_argument.h"
-#include "mongo/db/commands.h"
-#include "mongo/util/assert_util.h"
-
-namespace mongo {
-namespace rpc {
-
-namespace {
-// OP_COMMAND put some generic arguments in the metadata and some in the body.
-bool fieldGoesInMetadata(StringData commandName, StringData field) {
- if (!isGenericArgument(field))
- return false; // All non-generic arguments go to the body.
-
- // For some reason this goes in the body only for a single command...
- if (field == "$replData")
- return commandName != "replSetUpdatePosition";
-
- // These generic arguments went in the body.
- return !(field == "maxTimeMS" || field == "readConcern" || field == "writeConcern" ||
- field == "shardVersion");
-}
-} // namespace
-
-Message opCommandRequestFromOpMsgRequest(const OpMsgRequest& request) {
- const auto commandName = request.getCommandName();
-
- BufBuilder builder;
- builder.skip(mongo::MsgData::MsgDataHeaderSize); // Leave room for message header.
- builder.appendStr(request.getDatabase());
- builder.appendStr(commandName);
-
- // OP_COMMAND is only used when communicating with 3.4 nodes and they serialize their metadata
- // fields differently. In addition to field-level differences, some generic arguments are pulled
- // out to a metadata object, separate from the body. We do all down-conversion here so that the
- // rest of the code only has to deal with the current format.
- BSONObjBuilder metadataBuilder; // Will be appended to the message after we finish the body.
- {
- BSONObjBuilder bodyBuilder(builder);
- for (auto elem : request.body) {
- const auto fieldName = elem.fieldNameStringData();
- if (fieldName == "$configServerState") {
- metadataBuilder.appendAs(elem, "configsvr");
- } else if (fieldName == "$readPreference") {
- BSONObjBuilder ssmBuilder(metadataBuilder.subobjStart("$ssm"));
- ssmBuilder.append(elem);
- ssmBuilder.append("$secondaryOk",
- uassertStatusOK(ReadPreferenceSetting::fromInnerBSON(elem))
- .canRunOnSecondary());
- } else if (fieldName == "$db") {
- // skip
- } else if (fieldGoesInMetadata(commandName, fieldName)) {
- metadataBuilder.append(elem);
- } else {
- bodyBuilder.append(elem);
- }
- }
- for (auto&& seq : request.sequences) {
- invariant(seq.name.find('.') == std::string::npos); // Only support top-level for now.
- dassert(!bodyBuilder.asTempObj().hasField(seq.name));
- bodyBuilder.append(seq.name, seq.objs);
- }
- }
- metadataBuilder.obj().appendSelfToBufBuilder(builder);
-
- MsgData::View msg = builder.buf();
- msg.setLen(builder.len());
- msg.setOperation(dbCommand);
- return Message(builder.release());
-}
-
-} // namespace rpc
-} // namespace mongo
diff --git a/src/mongo/rpc/command_request_builder.h b/src/mongo/rpc/command_request_builder.h
deleted file mode 100644
index e890dd978b1..00000000000
--- a/src/mongo/rpc/command_request_builder.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * 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.
- */
-
-#pragma once
-
-#include "mongo/rpc/message.h"
-#include "mongo/rpc/op_msg.h"
-
-namespace mongo {
-namespace rpc {
-
-Message opCommandRequestFromOpMsgRequest(const OpMsgRequest& request);
-
-} // rpc
-} // mongo
diff --git a/src/mongo/rpc/command_request_builder_test.cpp b/src/mongo/rpc/command_request_builder_test.cpp
deleted file mode 100644
index e635cc5910e..00000000000
--- a/src/mongo/rpc/command_request_builder_test.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * 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.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/command_request.h"
-#include "mongo/rpc/command_request_builder.h"
-#include "mongo/unittest/unittest.h"
-
-namespace {
-
-using namespace mongo;
-
-TEST(CommandRequestBuilder, RoundTrip) {
- auto databaseName = "barbaz";
- auto commandName = "foobar";
-
- BSONObjBuilder metadataBob{};
- metadataBob.append("$replData", BSONObj());
- auto metadata = metadataBob.done();
-
- BSONObjBuilder commandArgsBob{};
- commandArgsBob.append(commandName, "baz");
- auto commandArgs = commandArgsBob.done();
-
- auto request = OpMsgRequest::fromDBAndBody(databaseName, commandArgs, metadata);
- request.sequences.push_back({"sequence", {BSON("a" << 1), BSON("b" << 2)}});
- auto msg = rpc::opCommandRequestFromOpMsgRequest(request);
-
- auto bodyAndSequence = BSONObjBuilder(commandArgs)
- .append("sequence", BSON_ARRAY(BSON("a" << 1) << BSON("b" << 2)))
- .obj();
-
- auto parsed = mongo::rpc::ParsedOpCommand::parse(msg);
-
- ASSERT_EQUALS(parsed.database, databaseName);
- ASSERT_EQUALS(StringData(parsed.body.firstElementFieldName()), commandName);
- ASSERT_BSONOBJ_EQ(parsed.metadata, metadata);
- ASSERT_BSONOBJ_EQ(parsed.body, bodyAndSequence);
-}
-
-TEST(CommandRequestBuilder, DownconvertSecondaryReadPreferenceToSSM) {
- auto readPref = BSON("mode"
- << "secondary");
- auto msg = rpc::opCommandRequestFromOpMsgRequest(
- OpMsgRequest::fromDBAndBody("admin", BSON("ping" << 1 << "$readPreference" << readPref)));
- auto parsed = mongo::rpc::ParsedOpCommand::parse(msg);
-
- ASSERT(!parsed.body.hasField("$readPreference"));
- ASSERT(!parsed.body.hasField("$ssm"));
- ASSERT(!parsed.metadata.hasField("$readPreference"));
-
- ASSERT_BSONOBJ_EQ(parsed.metadata["$ssm"]["$readPreference"].Obj(), readPref);
- ASSERT(parsed.metadata["$ssm"]["$secondaryOk"].trueValue());
-}
-
-TEST(CommandRequestBuilder, DownconvertPrimaryReadPreferenceToSSM) {
- auto readPref = BSON("mode"
- << "primary");
- auto msg = rpc::opCommandRequestFromOpMsgRequest(
- OpMsgRequest::fromDBAndBody("admin", BSON("ping" << 1 << "$readPreference" << readPref)));
- auto parsed = mongo::rpc::ParsedOpCommand::parse(msg);
-
- ASSERT(!parsed.body.hasField("$readPreference"));
- ASSERT(!parsed.body.hasField("$ssm"));
- ASSERT(!parsed.metadata.hasField("$readPreference"));
-
- ASSERT(!parsed.metadata["$ssm"]["$secondaryOk"].trueValue());
-}
-
-} // namespace
diff --git a/src/mongo/rpc/command_request_test.cpp b/src/mongo/rpc/command_request_test.cpp
deleted file mode 100644
index 5902766c2be..00000000000
--- a/src/mongo/rpc/command_request_test.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * 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.
- */
-
-#include "mongo/platform/basic.h"
-
-#include <iterator>
-#include <string>
-#include <vector>
-
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/command_request.h"
-#include "mongo/rpc/command_request_builder.h"
-#include "mongo/rpc/message.h"
-#include "mongo/unittest/unittest.h"
-#include "mongo/util/assert_util.h"
-
-namespace {
-
-using namespace mongo;
-
-TEST(CommandRequest, ParseAllFields) {
- std::vector<char> opCommandData;
-
- using std::begin;
- using std::end;
-
- auto writeString = [&opCommandData](const std::string& str) {
- opCommandData.insert(end(opCommandData), begin(str), end(str));
- opCommandData.push_back('\0');
- };
-
- auto writeObj = [&opCommandData](const BSONObj& obj) {
- opCommandData.insert(end(opCommandData), obj.objdata(), obj.objdata() + obj.objsize());
- };
-
- auto database = std::string{"ookokokokok"};
- writeString(database);
-
- auto commandName = std::string{"baz"};
- writeString(commandName);
-
- BSONObjBuilder commandArgsBob{};
- commandArgsBob.append("baz", "garply");
- auto commandArgs = commandArgsBob.done();
- writeObj(commandArgs);
-
- BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
- auto metadata = metadataBob.done();
- writeObj(metadata);
-
- Message toSend;
- toSend.setData(dbCommand, opCommandData.data(), opCommandData.size());
-
- auto opCmd = rpc::ParsedOpCommand::parse(toSend);
-
- ASSERT_EQUALS(opCmd.body.firstElementFieldName(), commandName);
- ASSERT_EQUALS(opCmd.database, database);
- ASSERT_BSONOBJ_EQ(opCmd.metadata, metadata);
- ASSERT_BSONOBJ_EQ(opCmd.body, commandArgs);
-}
-
-TEST(CommandRequest, EmptyCommandObjThrows) {
- std::vector<char> opCommandData;
-
- using std::begin;
- using std::end;
-
- auto writeString = [&opCommandData](const std::string& str) {
- opCommandData.insert(end(opCommandData), begin(str), end(str));
- opCommandData.push_back('\0');
- };
-
- auto writeObj = [&opCommandData](const BSONObj& obj) {
- opCommandData.insert(end(opCommandData), obj.objdata(), obj.objdata() + obj.objsize());
- };
-
- auto database = std::string{"someDb"};
- writeString(database);
-
- auto commandName = std::string{"baz"};
- writeString(commandName);
-
- auto commandArgs = BSONObj();
- writeObj(commandArgs);
-
- BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
- auto metadata = metadataBob.done();
- writeObj(metadata);
-
- Message msg;
- msg.setData(dbCommand, opCommandData.data(), opCommandData.size());
-
- ASSERT_THROWS_CODE(rpc::ParsedOpCommand::parse(msg), AssertionException, 39950);
-}
-
-TEST(CommandRequest, MismatchBetweenCommandNamesThrows) {
- std::vector<char> opCommandData;
-
- using std::begin;
- using std::end;
-
- auto writeString = [&opCommandData](const std::string& str) {
- opCommandData.insert(end(opCommandData), begin(str), end(str));
- opCommandData.push_back('\0');
- };
-
- auto writeObj = [&opCommandData](const BSONObj& obj) {
- opCommandData.insert(end(opCommandData), obj.objdata(), obj.objdata() + obj.objsize());
- };
-
- auto database = std::string{"someDb"};
- writeString(database);
-
- auto commandName = std::string{"fakeName"};
- writeString(commandName);
-
- auto commandArgs = BSON("realName" << 1);
- writeObj(commandArgs);
-
- BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
- auto metadata = metadataBob.done();
- writeObj(metadata);
-
- Message msg;
- msg.setData(dbCommand, opCommandData.data(), opCommandData.size());
-
- ASSERT_THROWS_CODE(rpc::ParsedOpCommand::parse(msg), AssertionException, 39950);
-}
-
-} // namespace
diff --git a/src/mongo/rpc/factory.cpp b/src/mongo/rpc/factory.cpp
index 94bd71f6c39..4d58677f8fd 100644
--- a/src/mongo/rpc/factory.cpp
+++ b/src/mongo/rpc/factory.cpp
@@ -30,10 +30,6 @@
#include "mongo/rpc/factory.h"
-#include "mongo/rpc/command_reply.h"
-#include "mongo/rpc/command_reply_builder.h"
-#include "mongo/rpc/command_request.h"
-#include "mongo/rpc/command_request_builder.h"
#include "mongo/rpc/legacy_reply.h"
#include "mongo/rpc/legacy_reply_builder.h"
#include "mongo/rpc/legacy_request.h"
@@ -54,11 +50,8 @@ Message messageFromOpMsgRequest(Protocol proto, const OpMsgRequest& request) {
return request.serialize();
case Protocol::kOpQuery:
return legacyRequestFromOpMsgRequest(request);
- case Protocol::kOpCommandV1:
- return opCommandRequestFromOpMsgRequest(request);
- default:
- MONGO_UNREACHABLE;
}
+ MONGO_UNREACHABLE;
}
std::unique_ptr<ReplyInterface> makeReply(const Message* unownedMessage) {
@@ -67,8 +60,6 @@ std::unique_ptr<ReplyInterface> makeReply(const Message* unownedMessage) {
return stdx::make_unique<OpMsgReply>(OpMsg::parseOwned(*unownedMessage));
case mongo::opReply:
return stdx::make_unique<LegacyReply>(unownedMessage);
- case mongo::dbCommandReply:
- return stdx::make_unique<CommandReply>(unownedMessage);
default:
uasserted(ErrorCodes::UnsupportedFormat,
str::stream() << "Received a reply message with unexpected opcode: "
@@ -82,8 +73,6 @@ OpMsgRequest opMsgRequestFromAnyProtocol(const Message& unownedMessage) {
return OpMsgRequest::parse(unownedMessage);
case mongo::dbQuery:
return opMsgRequestFromLegacyRequest(unownedMessage);
- case mongo::dbCommand:
- return opMsgRequestFromCommandRequest(unownedMessage);
default:
uasserted(ErrorCodes::UnsupportedFormat,
str::stream() << "Received a reply message with unexpected opcode: "
@@ -97,11 +86,8 @@ std::unique_ptr<ReplyBuilderInterface> makeReplyBuilder(Protocol protocol) {
return stdx::make_unique<OpMsgReplyBuilder>();
case Protocol::kOpQuery:
return stdx::make_unique<LegacyReplyBuilder>();
- case Protocol::kOpCommandV1:
- return stdx::make_unique<CommandReplyBuilder>();
- default:
- MONGO_UNREACHABLE;
}
+ MONGO_UNREACHABLE;
}
} // namespace rpc
diff --git a/src/mongo/rpc/message.h b/src/mongo/rpc/message.h
index a2fe2ec8c9d..4f2502f97bc 100644
--- a/src/mongo/rpc/message.h
+++ b/src/mongo/rpc/message.h
@@ -53,10 +53,10 @@ enum NetworkOp : int32_t {
dbGetMore = 2005,
dbDelete = 2006,
dbKillCursors = 2007,
- // dbCommand_DEPRECATED = 2008, //
- // dbCommandReply_DEPRECATED = 2009, //
- dbCommand = 2010,
- dbCommandReply = 2011,
+ // dbCommand_DEPRECATED = 2008, // These were used during 3.2 development, but never in a
+ // dbCommandReply_DEPRECATED = 2009, // stable release.
+ // dbCommand = 2010, // These were used for intra-cluster communication in 3.2, but never
+ // dbCommandReply = 2011, // by any driver. Deprecated in 3.6 by OP_MSG and removed in 4.2.
dbCompressed = 2012,
dbMsg = 2013,
};
@@ -69,15 +69,15 @@ inline bool isSupportedRequestNetworkOp(NetworkOp op) {
case dbGetMore:
case dbDelete:
case dbKillCursors:
- case dbCommand:
- case dbCompressed:
case dbMsg:
return true;
- case dbCommandReply:
+
+ case dbCompressed: // Can be used in requests, but must be decompressed prior to handling.
case opReply:
- default:
+ case opInvalid:
return false;
}
+ return false;
}
enum class LogicalOp {
@@ -88,7 +88,7 @@ enum class LogicalOp {
opGetMore,
opDelete,
opKillCursors,
- opCommand,
+ opCommand, // This just means a "command" is being run. Not related to the old OP_COMMAND.
opCompressed,
};
@@ -107,15 +107,16 @@ inline LogicalOp networkOpToLogicalOp(NetworkOp networkOp) {
case dbKillCursors:
return LogicalOp::opKillCursors;
case dbMsg:
- case dbCommand:
return LogicalOp::opCommand;
case dbCompressed:
return LogicalOp::opCompressed;
- default:
- int op = int(networkOp);
- massert(34348, str::stream() << "cannot translate opcode " << op, !op);
+ case opInvalid:
return LogicalOp::opInvalid;
+
+ case opReply:
+ break; // This has no logical op since it should never be used in a request.
}
+ msgasserted(34348, str::stream() << "cannot translate opcode " << int32_t(networkOp));
}
inline const char* networkOpToString(NetworkOp networkOp) {
@@ -136,19 +137,12 @@ inline const char* networkOpToString(NetworkOp networkOp) {
return "remove";
case dbKillCursors:
return "killcursors";
- case dbCommand:
- return "command";
- case dbCommandReply:
- return "commandReply";
case dbCompressed:
return "compressed";
case dbMsg:
return "msg";
- default:
- int op = static_cast<int>(networkOp);
- massert(16141, str::stream() << "cannot translate opcode " << op, !op);
- return "";
}
+ msgasserted(16141, str::stream() << "cannot translate opcode " << int32_t(networkOp));
}
inline const char* logicalOpToString(LogicalOp logicalOp) {
@@ -171,9 +165,11 @@ inline const char* logicalOpToString(LogicalOp logicalOp) {
return "command";
case LogicalOp::opCompressed:
return "compressed";
- default:
- MONGO_UNREACHABLE;
}
+
+ // Logical ops are always created in this process and never pulled out of network requests.
+ // Therefore, this could only be reached by memory corruptions or other severe bugs.
+ MONGO_UNREACHABLE;
}
namespace MSGHEADER {
diff --git a/src/mongo/rpc/metadata.h b/src/mongo/rpc/metadata.h
index b2b3ff13a3e..0231cfcebf5 100644
--- a/src/mongo/rpc/metadata.h
+++ b/src/mongo/rpc/metadata.h
@@ -41,8 +41,7 @@ class OperationContext;
class StringData;
/**
- * Utilities for converting metadata between the legacy OP_QUERY format and the new
- * OP_COMMAND format.
+ * Utilities for dealing with what used to be called metadata.
*/
namespace rpc {
diff --git a/src/mongo/rpc/metadata/client_metadata.h b/src/mongo/rpc/metadata/client_metadata.h
index 5e3b6dc69d4..288210539af 100644
--- a/src/mongo/rpc/metadata/client_metadata.h
+++ b/src/mongo/rpc/metadata/client_metadata.h
@@ -190,7 +190,7 @@ public:
void logClientMetadata(Client* client) const;
/**
- * Field name for OP_Command metadata that contains client metadata.
+ * Field name for requests that contains client metadata.
*/
static StringData fieldName();
diff --git a/src/mongo/rpc/metadata/client_metadata_ismaster.h b/src/mongo/rpc/metadata/client_metadata_ismaster.h
index d50f94728e4..ed7ae555802 100644
--- a/src/mongo/rpc/metadata/client_metadata_ismaster.h
+++ b/src/mongo/rpc/metadata/client_metadata_ismaster.h
@@ -74,7 +74,7 @@ public:
void setSeenIsMaster();
/**
- * Read from the $client section of OP_Command's metadata.
+ * Read from the $client field in requests.
*
* Returns an error if the $client section is not valid. It is valid for it to not exist though.
*
@@ -84,7 +84,7 @@ public:
static Status readFromMetadata(OperationContext* opCtx, BSONElement& elem);
/**
- * Write the $client section to OP_Command's metadata if there is a non-empty client metadata
+ * Write the $client section to request bodies if there is a non-empty client metadata
* connection with the current client.
*
* Thread-Safety:
@@ -94,7 +94,7 @@ public:
private:
// Optional client metadata document.
- // Set if client sees isMaster cmd or as part of OP_Command processing.
+ // Set if client sees isMaster cmd or the $client field.
// Thread-Safety:
// Can be read and written from the thread owning "Client".
// Can be read from other threads if they hold the "Client" lock.
diff --git a/src/mongo/rpc/protocol.cpp b/src/mongo/rpc/protocol.cpp
index 00fa6159ad4..4f531264400 100644
--- a/src/mongo/rpc/protocol.cpp
+++ b/src/mongo/rpc/protocol.cpp
@@ -47,7 +47,7 @@ namespace {
/**
* Protocols supported by order of preference.
*/
-const Protocol kPreferredProtos[] = {Protocol::kOpMsg, Protocol::kOpCommandV1, Protocol::kOpQuery};
+const Protocol kPreferredProtos[] = {Protocol::kOpMsg, Protocol::kOpQuery};
struct ProtocolSetAndName {
StringData name;
@@ -56,14 +56,11 @@ struct ProtocolSetAndName {
constexpr ProtocolSetAndName protocolSetNames[] = {
// Most common ones go first.
- {"all"_sd, supports::kAll}, // new mongod.
- {"opQueryAndOpMsg"_sd, supports::kOpQueryOnly | supports::kOpMsgOnly}, // new mongos.
- {"opQueryAndOpCommand"_sd, supports::kOpQueryOnly | supports::kOpCommandOnly}, // old mongod.
- {"opQueryOnly"_sd, supports::kOpQueryOnly}, // old mongos or very old client or mongod.
+ {"all"_sd, supports::kAll}, // new mongod and mongos or very new client.
+ {"opQueryOnly"_sd, supports::kOpQueryOnly}, // old mongos or mongod or moderately old client.
// Then the rest (these should never happen in production).
{"none"_sd, supports::kNone},
- {"opCommandOnly"_sd, supports::kOpCommandOnly},
{"opMsgOnly"_sd, supports::kOpMsgOnly},
};
@@ -75,8 +72,6 @@ Protocol protocolForMessage(const Message& message) {
return Protocol::kOpMsg;
case mongo::dbQuery:
return Protocol::kOpQuery;
- case mongo::dbCommand:
- return Protocol::kOpCommandV1;
default:
uasserted(ErrorCodes::UnsupportedFormat,
str::stream() << "Received a reply message with unexpected opcode: "
@@ -139,19 +134,6 @@ StatusWith<ProtocolSetAndWireVersionInfo> parseProtocolSetFromIsMasterReply(
return minWireExtractStatus;
}
- bool isMongos = false;
-
- std::string msgField;
- auto msgFieldExtractStatus = bsonExtractStringField(isMasterReply, "msg", &msgField);
-
- if (msgFieldExtractStatus == ErrorCodes::NoSuchKey) {
- isMongos = false;
- } else if (!msgFieldExtractStatus.isOK()) {
- return msgFieldExtractStatus;
- } else {
- isMongos = (msgField == "isdbgrid");
- }
-
if (minWireVersion < 0 || maxWireVersion < 0 ||
minWireVersion >= std::numeric_limits<int>::max() ||
maxWireVersion >= std::numeric_limits<int>::max()) {
@@ -166,11 +148,6 @@ StatusWith<ProtocolSetAndWireVersionInfo> parseProtocolSetFromIsMasterReply(
WireVersionInfo version{static_cast<int>(minWireVersion), static_cast<int>(maxWireVersion)};
auto protos = computeProtocolSet(version);
- if (isMongos) {
- // Remove support for protocols that mongos doesn't support.
- protos &= ~supports::kOpCommandOnly;
- }
-
return {{protos, version}};
}
@@ -180,14 +157,12 @@ ProtocolSet computeProtocolSet(const WireVersionInfo version) {
if (version.maxWireVersion >= WireVersion::SUPPORTS_OP_MSG) {
result |= supports::kOpMsgOnly;
}
- if (version.maxWireVersion >= WireVersion::FIND_COMMAND &&
- version.maxWireVersion <= WireVersion::SHARDED_TRANSACTIONS) {
- // Future versions may remove support for OP_COMMAND.
- result |= supports::kOpCommandOnly;
- }
if (version.minWireVersion <= WireVersion::RELEASE_2_4_AND_BEFORE) {
result |= supports::kOpQueryOnly;
}
+ // Note: this means anything using the internal handshake cannot talk to servers between 2.6
+ // and 3.6, since the servers will reply with higher minWireVersions. The shell should still
+ // be able to connect to those versions but will just use OP_QUERY to run commands.
}
return result;
}
diff --git a/src/mongo/rpc/protocol.h b/src/mongo/rpc/protocol.h
index 10e770271d3..e8eab90abb6 100644
--- a/src/mongo/rpc/protocol.h
+++ b/src/mongo/rpc/protocol.h
@@ -57,14 +57,9 @@ enum class Protocol : std::uint64_t {
kOpQuery = 1 << 0,
/**
- * The 3.2-3.6 OP_COMMAND protocol.
- */
- kOpCommandV1 = 1 << 1,
-
- /**
* The 3.6+ OP_MSG protocol.
*/
- kOpMsg = 1 << 2,
+ kOpMsg = 1 << 1,
};
/**
@@ -79,9 +74,8 @@ namespace supports {
const ProtocolSet kNone = ProtocolSet{0};
const ProtocolSet kOpQueryOnly = static_cast<ProtocolSet>(Protocol::kOpQuery);
-const ProtocolSet kOpCommandOnly = static_cast<ProtocolSet>(Protocol::kOpCommandV1);
const ProtocolSet kOpMsgOnly = static_cast<ProtocolSet>(Protocol::kOpMsg);
-const ProtocolSet kAll = kOpQueryOnly | kOpCommandOnly | kOpMsgOnly;
+const ProtocolSet kAll = kOpQueryOnly | kOpMsgOnly;
} // namespace supports
diff --git a/src/mongo/rpc/protocol_test.cpp b/src/mongo/rpc/protocol_test.cpp
index daa9e27a1b7..127b67bfb8c 100644
--- a/src/mongo/rpc/protocol_test.cpp
+++ b/src/mongo/rpc/protocol_test.cpp
@@ -51,7 +51,6 @@ const auto assert_negotiated = [](ProtocolSet fst, ProtocolSet snd, Protocol pro
TEST(Protocol, SuccessfulNegotiation) {
assert_negotiated(supports::kAll, supports::kAll, Protocol::kOpMsg);
assert_negotiated(supports::kAll, supports::kOpMsgOnly, Protocol::kOpMsg);
- assert_negotiated(supports::kAll, supports::kOpCommandOnly, Protocol::kOpCommandV1);
assert_negotiated(supports::kAll, supports::kOpQueryOnly, Protocol::kOpQuery);
}
@@ -63,21 +62,21 @@ const auto assert_not_negotiated = [](ProtocolSet fst, ProtocolSet snd) {
};
TEST(Protocol, FailedNegotiation) {
- assert_not_negotiated(supports::kOpQueryOnly, supports::kOpCommandOnly);
+ assert_not_negotiated(supports::kOpQueryOnly, supports::kOpMsgOnly);
assert_not_negotiated(supports::kAll, supports::kNone);
assert_not_negotiated(supports::kOpQueryOnly, supports::kNone);
- assert_not_negotiated(supports::kOpCommandOnly, supports::kNone);
+ assert_not_negotiated(supports::kOpMsgOnly, supports::kNone);
}
TEST(Protocol, parseProtocolSetFromIsMasterReply) {
{
- // MongoDB 3.8
- auto mongod38 =
+ // MongoDB 4.0
+ auto mongod40 =
BSON("maxWireVersion" << static_cast<int>(WireVersion::REPLICA_SET_TRANSACTIONS)
<< "minWireVersion"
<< static_cast<int>(WireVersion::RELEASE_2_4_AND_BEFORE));
- ASSERT_EQ(assertGet(parseProtocolSetFromIsMasterReply(mongod38)).protocolSet,
+ ASSERT_EQ(assertGet(parseProtocolSetFromIsMasterReply(mongod40)).protocolSet,
supports::kAll);
}
{
@@ -98,7 +97,7 @@ TEST(Protocol, parseProtocolSetFromIsMasterReply) {
<< static_cast<int>(WireVersion::RELEASE_2_4_AND_BEFORE));
ASSERT_EQ(assertGet(parseProtocolSetFromIsMasterReply(mongod32)).protocolSet,
- supports::kOpQueryOnly | supports::kOpCommandOnly);
+ supports::kOpQueryOnly); // This used to also include OP_COMMAND.
}
{
// MongoDB 3.2 (mongos)
diff --git a/src/mongo/rpc/reply_builder_test.cpp b/src/mongo/rpc/reply_builder_test.cpp
index f4f8ac58ef4..dd0d36a5739 100644
--- a/src/mongo/rpc/reply_builder_test.cpp
+++ b/src/mongo/rpc/reply_builder_test.cpp
@@ -31,8 +31,6 @@
#include "mongo/bson/util/builder.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/json.h"
-#include "mongo/rpc/command_reply.h"
-#include "mongo/rpc/command_reply_builder.h"
#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/rpc/legacy_reply.h"
#include "mongo/rpc/legacy_reply_builder.h"
@@ -55,11 +53,6 @@ TEST(LegacyReplyBuilder, RoundTrip) {
testRoundTrip<rpc::LegacyReply>(r, true);
}
-TEST(CommandReplyBuilder, RoundTrip) {
- rpc::CommandReplyBuilder r;
- testRoundTrip<rpc::CommandReply>(r, false);
-}
-
TEST(OpMsgReplyBuilder, RoundTrip) {
rpc::OpMsgReplyBuilder r;
testRoundTrip<rpc::OpMsgReply>(r, true);
@@ -73,11 +66,6 @@ TEST(LegacyReplyBuilder, Errors) {
testErrors<rpc::LegacyReply>(r);
}
-TEST(CommandReplyBuilder, Errors) {
- rpc::CommandReplyBuilder r;
- testErrors<rpc::CommandReply>(r);
-}
-
TEST(OpMsgReplyBuilder, Errors) {
rpc::OpMsgReplyBuilder r;
testErrors<rpc::OpMsgReply>(r);
@@ -128,20 +116,6 @@ BSONObj buildErrReply(const Status status, const BSONObj& extraInfo = {}) {
return bob.obj();
}
-TEST(CommandReplyBuilder, CommandError) {
- const Status status(ErrorCodes::InvalidLength, "Response payload too long");
- BSONObj metadata = buildMetadata();
- rpc::CommandReplyBuilder replyBuilder;
- replyBuilder.setCommandReply(status);
- replyBuilder.setMetadata(metadata);
- auto msg = replyBuilder.done();
-
- rpc::CommandReply parsed(&msg);
-
- ASSERT_BSONOBJ_EQ(parsed.getMetadata(), metadata);
- ASSERT_BSONOBJ_EQ(parsed.getCommandReply(), buildErrReply(status));
-}
-
TEST(LegacyReplyBuilder, CommandError) {
const Status status(ErrorCodes::InvalidLength, "Response payload too long");
BSONObj metadata = buildMetadata();
diff --git a/src/mongo/s/service_entry_point_mongos.cpp b/src/mongo/s/service_entry_point_mongos.cpp
index 366c05d3f60..1172f20058e 100644
--- a/src/mongo/s/service_entry_point_mongos.cpp
+++ b/src/mongo/s/service_entry_point_mongos.cpp
@@ -72,7 +72,6 @@ DbResponse ServiceEntryPointMongos::handleRequest(OperationContext* opCtx, const
uassert(ErrorCodes::IllegalOperation,
str::stream() << "Message type " << op << " is not supported.",
isSupportedRequestNetworkOp(op) &&
- op != dbCommand && // mongos never implemented OP_COMMAND ingress support.
op != dbCompressed); // Decompression should be handled above us.
// Start a new LastError session. Any exceptions thrown from here onwards will be returned
diff --git a/src/mongo/shell/shell_options.cpp b/src/mongo/shell/shell_options.cpp
index 311d7a22a0d..fd195020840 100644
--- a/src/mongo/shell/shell_options.cpp
+++ b/src/mongo/shell/shell_options.cpp
@@ -216,7 +216,7 @@ Status addMongoShellOptions(moe::OptionSection* options) {
options
->addOptionChaining(
- "rpcProtocols", "rpcProtocols", moe::String, " none, opQueryOnly, opCommandOnly, all")
+ "rpcProtocols", "rpcProtocols", moe::String, " none, opQueryOnly, opMsgOnly, all")
.hidden();
auto ret = addMessageCompressionOptions(options, true);
@@ -379,8 +379,7 @@ Status storeMongoShellOptions(const moe::Environment& params,
if (!parsedRPCProtos.isOK()) {
uasserted(28653,
str::stream() << "Unknown RPC Protocols: '" << protos
- << "'. Valid values are {none, opQueryOnly, "
- << "opCommandOnly, all}");
+ << "'. Valid values are {none, opQueryOnly, opMsgOnly, all}");
}
shellGlobalParams.rpcProtocols = parsedRPCProtos.getValue();
}
diff --git a/src/mongo/tools/bridge.cpp b/src/mongo/tools/bridge.cpp
index 01093145986..6938882953d 100644
--- a/src/mongo/tools/bridge.cpp
+++ b/src/mongo/tools/bridge.cpp
@@ -40,7 +40,6 @@
#include "mongo/db/service_context.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/platform/random.h"
-#include "mongo/rpc/command_request.h"
#include "mongo/rpc/factory.h"
#include "mongo/rpc/message.h"
#include "mongo/rpc/reply_builder_interface.h"
@@ -288,7 +287,7 @@ DbResponse ServiceEntryPointBridge::handleRequest(OperationContext* opCtx, const
boost::optional<OpMsgRequest> cmdRequest;
if ((request.operation() == dbQuery &&
NamespaceString(DbMessage(request).getns()).isCommand()) ||
- request.operation() == dbCommand || request.operation() == dbMsg) {
+ request.operation() == dbMsg) {
cmdRequest = rpc::opMsgRequestFromAnyProtocol(request);
dest.extractHostInfo(*cmdRequest);
@@ -350,10 +349,10 @@ DbResponse ServiceEntryPointBridge::handleRequest(OperationContext* opCtx, const
uassertStatusOK(dest->sinkMessage(request));
// Send the message we received from 'source' to 'dest'. 'dest' returns a response for
- // OP_QUERY, OP_GET_MORE, and OP_COMMAND messages that we respond with.
+ // OP_QUERY, OP_GET_MORE, and OP_MSG messages that we respond with.
if (!isFireAndForgetCommand &&
(request.operation() == dbQuery || request.operation() == dbGetMore ||
- request.operation() == dbCommand || request.operation() == dbMsg)) {
+ request.operation() == dbMsg)) {
// TODO dbMsg moreToCome
// Forward the message to 'dest' and receive its reply in 'response'.
auto response = uassertStatusOK(dest->sourceMessage());
diff --git a/src/mongo/transport/SConscript b/src/mongo/transport/SConscript
index 0f61fbcf12c..2990aede9ea 100644
--- a/src/mongo/transport/SConscript
+++ b/src/mongo/transport/SConscript
@@ -187,8 +187,7 @@ env.CppUnitTest(
'transport_layer_mock',
'$BUILD_DIR/mongo/db/dbmessage',
'$BUILD_DIR/mongo/db/service_context',
- '$BUILD_DIR/mongo/rpc/command_reply',
- '$BUILD_DIR/mongo/rpc/command_request',
+ '$BUILD_DIR/mongo/rpc/rpc',
'$BUILD_DIR/mongo/unittest/unittest',
'$BUILD_DIR/mongo/util/clock_source_mock',
],