summaryrefslogtreecommitdiff
path: root/src/mongo/rpc
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2017-05-23 18:34:32 -0400
committerMathias Stearn <mathias@10gen.com>2017-06-19 19:02:31 -0400
commit36c13338c54d9cd7bb978d56487fc692374c8255 (patch)
treedfb18cc38414059dd043da31bb940f6192a4d994 /src/mongo/rpc
parent47856e523e3d3c842f95ec277f33728130ad14dd (diff)
downloadmongo-36c13338c54d9cd7bb978d56487fc692374c8255.tar.gz
SERVER-29319 Replace RequestBuilderInterface with OpMsgRequest
Diffstat (limited to 'src/mongo/rpc')
-rw-r--r--src/mongo/rpc/command_request_builder.cpp103
-rw-r--r--src/mongo/rpc/command_request_builder.h49
-rw-r--r--src/mongo/rpc/command_request_builder_test.cpp47
-rw-r--r--src/mongo/rpc/command_request_test.cpp74
-rw-r--r--src/mongo/rpc/factory.cpp13
-rw-r--r--src/mongo/rpc/factory.h16
-rw-r--r--src/mongo/rpc/legacy_request_builder.cpp98
-rw-r--r--src/mongo/rpc/legacy_request_builder.h35
-rw-r--r--src/mongo/rpc/metadata.cpp27
-rw-r--r--src/mongo/rpc/metadata.h6
-rw-r--r--src/mongo/rpc/op_msg_rpc_impls.h33
-rw-r--r--src/mongo/rpc/request_builder_interface.h99
12 files changed, 206 insertions, 394 deletions
diff --git a/src/mongo/rpc/command_request_builder.cpp b/src/mongo/rpc/command_request_builder.cpp
index 9b784db1841..4a10cc7656f 100644
--- a/src/mongo/rpc/command_request_builder.cpp
+++ b/src/mongo/rpc/command_request_builder.cpp
@@ -30,80 +30,71 @@
#include "mongo/rpc/command_request_builder.h"
-#include <utility>
-
#include "mongo/client/read_preference.h"
-#include "mongo/stdx/memory.h"
+#include "mongo/db/commands.h"
#include "mongo/util/assert_util.h"
-#include "mongo/util/net/message.h"
namespace mongo {
namespace rpc {
-CommandRequestBuilder::CommandRequestBuilder() : CommandRequestBuilder(Message()) {}
+namespace {
+// OP_COMMAND put some generic arguments in the metadata and some in the body.
+bool fieldGoesInMetadata(StringData commandName, StringData field) {
+ if (!Command::isGenericArgument(field))
+ return false; // All non-generic arguments go to the body.
-CommandRequestBuilder::~CommandRequestBuilder() {}
+ // For some reason this goes in the body only for a single command...
+ if (field == "$replData")
+ return commandName != "replSetUpdatePosition";
-CommandRequestBuilder::CommandRequestBuilder(Message&& message) : _message{std::move(message)} {
- _builder.skip(mongo::MsgData::MsgDataHeaderSize); // Leave room for message header.
+ // These generic arguments went in the body.
+ return !(field == "maxTimeMS" || field == "readConcern" || field == "writeConcern" ||
+ field == "shardVersion");
}
+} // namespace
-CommandRequestBuilder& CommandRequestBuilder::setDatabase(StringData database) {
- invariant(_state == State::kDatabase);
- _builder.appendStr(database);
- _state = State::kCommandName;
- return *this;
-}
+Message opCommandRequestFromOpMsgRequest(const OpMsgRequest& request) {
+ invariant(request.sequences.empty()); // Not supported yet.
-CommandRequestBuilder& CommandRequestBuilder::setCommandName(StringData commandName) {
- invariant(_state == State::kCommandName);
- _builder.appendStr(commandName);
- _state = State::kCommandArgs;
- return *this;
-}
+ const auto commandName = request.getCommandName();
-CommandRequestBuilder& CommandRequestBuilder::setCommandArgs(BSONObj commandArgs) {
- invariant(_state == State::kCommandArgs);
- commandArgs.appendSelfToBufBuilder(_builder);
- _state = State::kMetadata;
- return *this;
-}
+ BufBuilder builder;
+ builder.skip(mongo::MsgData::MsgDataHeaderSize); // Leave room for message header.
+ builder.appendStr(request.getDatabase());
+ builder.appendStr(commandName);
-CommandRequestBuilder& CommandRequestBuilder::setMetadata(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 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 if (elem.fieldNameStringData() == "$readPreference") {
- BSONObjBuilder ssmBuilder(bob.subobjStart("$ssm"));
- ssmBuilder.append(elem);
- ssmBuilder.append(
- "$secondaryOk",
- uassertStatusOK(ReadPreferenceSetting::fromInnerBSON(elem)).canRunOnSecondary());
- } else {
- bob.append(elem);
+ // 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);
+ }
}
}
- _state = State::kInputDocs;
- return *this;
-}
-
-Protocol CommandRequestBuilder::getProtocol() const {
- return rpc::Protocol::kOpCommandV1;
-}
+ metadataBuilder.obj().appendSelfToBufBuilder(builder);
-Message CommandRequestBuilder::done() {
- invariant(_state == State::kInputDocs);
- MsgData::View msg = _builder.buf();
- msg.setLen(_builder.len());
+ MsgData::View msg = builder.buf();
+ msg.setLen(builder.len());
msg.setOperation(dbCommand);
- _message.setData(_builder.release()); // transfer ownership to Message.
- _state = State::kDone;
- return std::move(_message);
+ return Message(builder.release());
}
} // namespace rpc
diff --git a/src/mongo/rpc/command_request_builder.h b/src/mongo/rpc/command_request_builder.h
index 7eb3db408b5..0e3ae41fbca 100644
--- a/src/mongo/rpc/command_request_builder.h
+++ b/src/mongo/rpc/command_request_builder.h
@@ -28,58 +28,13 @@
#pragma once
-#include <memory>
-
-#include "mongo/base/string_data.h"
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/protocol.h"
-#include "mongo/rpc/request_builder_interface.h"
#include "mongo/util/net/message.h"
+#include "mongo/util/net/op_msg.h"
namespace mongo {
namespace rpc {
-/**
- * Constructs an OP_COMMAND message.
- */
-class CommandRequestBuilder : public RequestBuilderInterface {
-public:
- /**
- * Constructs an OP_COMMAND in a new buffer.
- */
- CommandRequestBuilder();
-
- ~CommandRequestBuilder() final;
-
- /**
- * Construct an OP_COMMAND in an existing buffer. Ownership of the buffer will be
- * transfered to the CommandRequestBuilder.
- */
- CommandRequestBuilder(Message&& message);
-
- CommandRequestBuilder& setDatabase(StringData database) final;
-
- CommandRequestBuilder& setCommandName(StringData commandName) final;
-
- CommandRequestBuilder& setCommandArgs(BSONObj commandArgs) final;
-
- CommandRequestBuilder& setMetadata(BSONObj metadata) final;
-
- Protocol getProtocol() const 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;
-
-private:
- BufBuilder _builder{};
- Message _message;
-
- State _state{State::kDatabase};
-};
+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
index fe9539d41d2..a8b3c9af8f1 100644
--- a/src/mongo/rpc/command_request_builder_test.cpp
+++ b/src/mongo/rpc/command_request_builder_test.cpp
@@ -37,12 +37,12 @@ namespace {
using namespace mongo;
-TEST(RequestBuilder, RoundTrip) {
+TEST(CommandRequestBuilder, RoundTrip) {
auto databaseName = "barbaz";
auto commandName = "foobar";
BSONObjBuilder metadataBob{};
- metadataBob.append("foo", "bar");
+ metadataBob.append("$replData", BSONObj());
auto metadata = metadataBob.done();
BSONObjBuilder commandArgsBob{};
@@ -61,18 +61,8 @@ TEST(RequestBuilder, RoundTrip) {
inputDoc3Bob.append("g", "p");
auto inputDoc3 = inputDoc3Bob.done();
- BufBuilder inputDocs;
- inputDoc1.appendSelfToBufBuilder(inputDocs);
- inputDoc2.appendSelfToBufBuilder(inputDocs);
- inputDoc3.appendSelfToBufBuilder(inputDocs);
-
- rpc::CommandRequestBuilder r;
-
- auto msg = r.setDatabase(databaseName)
- .setCommandName(commandName)
- .setCommandArgs(commandArgs)
- .setMetadata(metadata)
- .done();
+ auto msg = rpc::opCommandRequestFromOpMsgRequest(
+ OpMsgRequest::fromDBAndBody(databaseName, commandArgs, metadata));
auto parsed = mongo::rpc::ParsedOpCommand::parse(msg);
@@ -82,4 +72,33 @@ TEST(RequestBuilder, RoundTrip) {
ASSERT_BSONOBJ_EQ(parsed.body, commandArgs);
}
+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
index 17fc056ef68..830c1f04472 100644
--- a/src/mongo/rpc/command_request_test.cpp
+++ b/src/mongo/rpc/command_request_test.cpp
@@ -86,22 +86,72 @@ TEST(CommandRequest, ParseAllFields) {
}
TEST(CommandRequest, EmptyCommandObjThrows) {
- rpc::CommandRequestBuilder crb;
- crb.setDatabase("someDb");
- crb.setCommandName("ping");
- crb.setCommandArgs(BSONObj());
- crb.setMetadata(BSONObj());
- auto msg = crb.done();
+ 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), UserException, 39950);
}
TEST(CommandRequest, MismatchBetweenCommandNamesThrows) {
- rpc::CommandRequestBuilder crb;
- crb.setDatabase("someDb");
- crb.setCommandName("ping");
- crb.setCommandArgs(BSON("launchMissiles" << 1));
- crb.setMetadata(BSONObj());
- auto msg = crb.done();
+ 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), UserException, 39950);
}
diff --git a/src/mongo/rpc/factory.cpp b/src/mongo/rpc/factory.cpp
index 38bcbdbfeb8..6ef513c0284 100644
--- a/src/mongo/rpc/factory.cpp
+++ b/src/mongo/rpc/factory.cpp
@@ -48,19 +48,14 @@
namespace mongo {
namespace rpc {
-std::unique_ptr<RequestBuilderInterface> makeRequestBuilder(ProtocolSet clientProtos,
- ProtocolSet serverProtos) {
- return makeRequestBuilder(uassertStatusOK(negotiate(clientProtos, serverProtos)));
-}
-
-std::unique_ptr<RequestBuilderInterface> makeRequestBuilder(Protocol proto) {
+Message messageFromOpMsgRequest(Protocol proto, const OpMsgRequest& request) {
switch (proto) {
case Protocol::kOpMsg:
- return stdx::make_unique<OpMsgRequestBuilder>();
+ return request.serialize();
case Protocol::kOpQuery:
- return stdx::make_unique<LegacyRequestBuilder>();
+ return legacyRequestFromOpMsgRequest(request);
case Protocol::kOpCommandV1:
- return stdx::make_unique<CommandRequestBuilder>();
+ return opCommandRequestFromOpMsgRequest(request);
default:
MONGO_UNREACHABLE;
}
diff --git a/src/mongo/rpc/factory.h b/src/mongo/rpc/factory.h
index 08b3ef0a8d1..fb3f7c0b853 100644
--- a/src/mongo/rpc/factory.h
+++ b/src/mongo/rpc/factory.h
@@ -44,21 +44,21 @@ class Message;
namespace rpc {
class ReplyBuilderInterface;
class ReplyInterface;
-class RequestBuilderInterface;
/**
* Returns the appropriate concrete RequestBuilder. Throws if one cannot be chosen.
*/
-std::unique_ptr<RequestBuilderInterface> makeRequestBuilder(ProtocolSet clientProtos,
- ProtocolSet serverProtos);
-
-std::unique_ptr<RequestBuilderInterface> makeRequestBuilder(Protocol proto);
+std::unique_ptr<ReplyInterface> makeReply(const Message* unownedMessage);
/**
- * Returns the appropriate concrete Reply according to the contents of the message.
- * Throws if one cannot be chosen.
+ * Serializes an OpMsgRequest for a server that speaks the requested protocol.
*/
-std::unique_ptr<ReplyInterface> makeReply(const Message* unownedMessage);
+Message messageFromOpMsgRequest(Protocol proto, const OpMsgRequest&);
+inline Message messageFromOpMsgRequest(ProtocolSet clientProtos,
+ ProtocolSet serverProtos,
+ const OpMsgRequest& request) {
+ return messageFromOpMsgRequest(uassertStatusOK(negotiate(clientProtos, serverProtos)), request);
+}
/**
* Parses the message (from any protocol) into an OpMsgRequest.
diff --git a/src/mongo/rpc/legacy_request_builder.cpp b/src/mongo/rpc/legacy_request_builder.cpp
index 87fc766a608..f4a9252f921 100644
--- a/src/mongo/rpc/legacy_request_builder.cpp
+++ b/src/mongo/rpc/legacy_request_builder.cpp
@@ -33,6 +33,8 @@
#include <tuple>
#include <utility>
+#include "mongo/client/dbclientinterface.h"
+#include "mongo/client/read_preference.h"
#include "mongo/db/namespace_string.h"
#include "mongo/rpc/metadata.h"
#include "mongo/stdx/memory.h"
@@ -42,65 +44,61 @@
namespace mongo {
namespace rpc {
-LegacyRequestBuilder::LegacyRequestBuilder() : LegacyRequestBuilder(Message()) {}
-
-LegacyRequestBuilder::~LegacyRequestBuilder() {}
-
-LegacyRequestBuilder::LegacyRequestBuilder(Message&& message) : _message{std::move(message)} {
- _builder.skip(mongo::MsgData::MsgDataHeaderSize);
-}
-
-LegacyRequestBuilder& LegacyRequestBuilder::setDatabase(StringData database) {
- invariant(_state == State::kDatabase);
- _ns = NamespaceString(database, "$cmd").toString();
- _state = State::kCommandName;
- return *this;
+namespace {
+/**
+ * Given a command request, attempts to construct a legacy command
+ * object and query flags bitfield augmented with the given metadata.
+ */
+BSONObj downconvertRequestBody(const OpMsgRequest& request, int* queryOptions) {
+ invariant(request.sequences.empty()); // Not supported yet.
+ *queryOptions = 0;
+
+ if (auto readPref = request.body["$readPreference"]) {
+ auto parsed = ReadPreferenceSetting::fromInnerBSON(readPref);
+ if (parsed.isOK() && parsed.getValue().canRunOnSecondary()) {
+ *queryOptions |= QueryOption_SlaveOk;
+ }
+
+ BSONObjBuilder outer;
+ {
+ BSONObjBuilder inner(outer.subobjStart("$query"));
+ for (auto field : request.body) {
+ const auto name = field.fieldNameStringData();
+ if (name == "$readPreference" || name == "$db") {
+ // skip field.
+ } else {
+ inner.append(field);
+ }
+ }
+ }
+ outer.append(readPref);
+ return outer.obj();
+ } else {
+ return request.body.removeField("$db"); // No additional downconversion needed.
+ }
}
+} // namespace
-LegacyRequestBuilder& LegacyRequestBuilder::setCommandName(StringData commandName) {
- invariant(_state == State::kCommandName);
- // no op, as commandName is the first element of commandArgs
- _state = State::kCommandArgs;
- return *this;
-}
+Message legacyRequestFromOpMsgRequest(const OpMsgRequest& request) {
+ BufBuilder builder;
+ builder.skip(mongo::MsgData::MsgDataHeaderSize);
-LegacyRequestBuilder& LegacyRequestBuilder::setCommandArgs(BSONObj commandArgs) {
- invariant(_state == State::kCommandArgs);
- _commandArgs = std::move(commandArgs);
- _state = State::kMetadata;
- return *this;
-}
+ const auto cmdNS = NamespaceString(request.getDatabase(), "").getCommandNS().toString();
-LegacyRequestBuilder& LegacyRequestBuilder::setMetadata(BSONObj metadata) {
- invariant(_state == State::kMetadata);
- BSONObj legacyCommandArgs;
int queryOptions;
+ const auto downconvertedBody = downconvertRequestBody(request, &queryOptions);
- std::tie(legacyCommandArgs, queryOptions) =
- rpc::downconvertRequestMetadata(std::move(_commandArgs), std::move(metadata));
-
- _builder.appendNum(queryOptions); // queryOptions
- _builder.appendStr(_ns);
- _builder.appendNum(0); // nToSkip
- _builder.appendNum(1); // nToReturn
+ builder.appendNum(queryOptions);
+ builder.appendStr(cmdNS);
+ builder.appendNum(0); // nToSkip
+ builder.appendNum(1); // nToReturn
- legacyCommandArgs.appendSelfToBufBuilder(_builder);
- _state = State::kInputDocs;
- return *this;
-}
-
-Protocol LegacyRequestBuilder::getProtocol() const {
- return rpc::Protocol::kOpQuery;
-}
+ downconvertedBody.appendSelfToBufBuilder(builder);
-Message LegacyRequestBuilder::done() {
- invariant(_state == State::kInputDocs);
- MsgData::View msg = _builder.buf();
- msg.setLen(_builder.len());
+ MsgData::View msg = builder.buf();
+ msg.setLen(builder.len());
msg.setOperation(dbQuery);
- _message.setData(_builder.release());
- _state = State::kDone;
- return std::move(_message);
+ return Message(builder.release());
}
} // namespace rpc
diff --git a/src/mongo/rpc/legacy_request_builder.h b/src/mongo/rpc/legacy_request_builder.h
index 26bcb9903f1..31c8c9b0f77 100644
--- a/src/mongo/rpc/legacy_request_builder.h
+++ b/src/mongo/rpc/legacy_request_builder.h
@@ -28,44 +28,13 @@
#pragma once
-#include <memory>
-
-#include "mongo/base/string_data.h"
-#include "mongo/db/jsobj.h"
-#include "mongo/rpc/request_builder_interface.h"
#include "mongo/util/net/message.h"
+#include "mongo/util/net/op_msg.h"
namespace mongo {
namespace rpc {
-class LegacyRequestBuilder : public RequestBuilderInterface {
-public:
- LegacyRequestBuilder();
- ~LegacyRequestBuilder() final;
-
- LegacyRequestBuilder(Message&&);
-
- LegacyRequestBuilder& setDatabase(StringData database) final;
- LegacyRequestBuilder& setCommandName(StringData commandName) final;
- LegacyRequestBuilder& setMetadata(BSONObj metadata) final;
- LegacyRequestBuilder& setCommandArgs(BSONObj commandArgs) final;
-
- Protocol getProtocol() const final;
-
- Message done() final;
-
-private:
- Message _message;
- BufBuilder _builder{};
-
- // we need to stash this as we need metadata to
- // upconvert.
- BSONObj _commandArgs;
-
- std::string _ns{}; // copied to in setDatabase
-
- State _state{State::kDatabase};
-};
+Message legacyRequestFromOpMsgRequest(const OpMsgRequest& request);
} // namespace rpc
} // namespace mongo
diff --git a/src/mongo/rpc/metadata.cpp b/src/mongo/rpc/metadata.cpp
index 715532f453d..69d7306ef45 100644
--- a/src/mongo/rpc/metadata.cpp
+++ b/src/mongo/rpc/metadata.cpp
@@ -161,33 +161,6 @@ CommandAndMetadata upconvertRequestMetadata(BSONObj legacyCmdObj, int queryFlags
return std::make_tuple(logicalTimeCommandBob.obj(), metadataBob.obj());
}
-LegacyCommandAndFlags downconvertRequestMetadata(BSONObj cmdObj, BSONObj metadata) {
- int legacyQueryFlags = 0;
- if (auto logicalTime = metadata[LogicalTimeMetadata::fieldName()]) {
- BSONObjBuilder logicalTimeCommandBob(std::move(cmdObj));
- logicalTimeCommandBob.append(logicalTime);
- cmdObj = logicalTimeCommandBob.obj();
- }
-
- auto readPref = metadata["$readPreference"];
- if (!readPref)
- readPref = cmdObj["$readPreference"];
-
- if (readPref) {
- BSONObjBuilder bob;
- bob.append("$query", cmdObj);
- bob.append(readPref);
- cmdObj = bob.obj();
-
- auto parsed = ReadPreferenceSetting::fromInnerBSON(readPref);
- if (parsed.isOK() && parsed.getValue().canRunOnSecondary()) {
- legacyQueryFlags |= QueryOption_SlaveOk;
- }
- }
-
- return std::make_tuple(cmdObj, std::move(legacyQueryFlags));
-}
-
CommandReplyWithMetadata upconvertReplyMetadata(const BSONObj& legacyReply) {
BSONObjBuilder commandReplyBob;
BSONObjBuilder metadataBob;
diff --git a/src/mongo/rpc/metadata.h b/src/mongo/rpc/metadata.h
index 8d3482be458..3745a1d55ca 100644
--- a/src/mongo/rpc/metadata.h
+++ b/src/mongo/rpc/metadata.h
@@ -73,12 +73,6 @@ using LegacyCommandAndFlags = std::tuple<BSONObj, int>;
CommandAndMetadata upconvertRequestMetadata(BSONObj legacyCmdObj, int queryFlags);
/**
- * Given a command object and a metadata object, attempts to construct a legacy command
- * object and query flags bitfield augmented with the given metadata.
- */
-LegacyCommandAndFlags downconvertRequestMetadata(BSONObj cmdObj, BSONObj metadata);
-
-/**
* A command reply and associated metadata object.
*/
using CommandReplyWithMetadata = std::tuple<BSONObj, BSONObj>;
diff --git a/src/mongo/rpc/op_msg_rpc_impls.h b/src/mongo/rpc/op_msg_rpc_impls.h
index adc9a8f24f5..b6b3bab1073 100644
--- a/src/mongo/rpc/op_msg_rpc_impls.h
+++ b/src/mongo/rpc/op_msg_rpc_impls.h
@@ -30,7 +30,6 @@
#include "mongo/rpc/reply_builder_interface.h"
#include "mongo/rpc/reply_interface.h"
-#include "mongo/rpc/request_builder_interface.h"
#include "mongo/util/net/op_msg.h"
namespace mongo {
@@ -85,37 +84,5 @@ private:
OpMsgBuilder _builder;
};
-class OpMsgRequestBuilder final : public rpc::RequestBuilderInterface {
-public:
- RequestBuilderInterface& setDatabase(StringData database) override {
- _db = database.toString();
- return *this;
- }
- RequestBuilderInterface& setCommandName(StringData commandName) override {
- // No-op because command name is first field name in command body.
- return *this;
- }
- RequestBuilderInterface& setCommandArgs(BSONObj reply) override {
- _builder.beginBody().appendElements(reply);
- return *this;
- }
- RequestBuilderInterface& setMetadata(BSONObj metadata) override {
- _builder.resumeBody().appendElements(metadata);
- return *this;
- }
- rpc::Protocol getProtocol() const override {
- return rpc::Protocol::kOpMsg;
- }
- Message done() override {
- invariant(!_db.empty());
- _builder.resumeBody().append("$db", _db);
- return _builder.finish();
- }
-
-private:
- std::string _db;
- OpMsgBuilder _builder;
-};
-
} // namespace rpc
} // namespace mongo
diff --git a/src/mongo/rpc/request_builder_interface.h b/src/mongo/rpc/request_builder_interface.h
deleted file mode 100644
index aef872cb0b4..00000000000
--- a/src/mongo/rpc/request_builder_interface.h
+++ /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.
- */
-
-#pragma once
-
-#include <memory>
-
-#include "mongo/base/disallow_copying.h"
-#include "mongo/rpc/protocol.h"
-
-namespace mongo {
-class Message;
-class BSONObj;
-class StringData;
-
-namespace rpc {
-
-/**
- * Constructs an RPC request.
- */
-class RequestBuilderInterface {
- MONGO_DISALLOW_COPYING(RequestBuilderInterface);
-
-public:
- /**
- * Request builders must have their fields set in order as they are immediately written into
- * the underlying message buffer. This enum represents the next field that can be written
- * into the builder. Note that when the builder is in state 'kInputDocs', multiple input
- * docs can be added. After the builder's done() method is called it is in state 'kDone',
- * and no further methods can be called.
- */
- enum class State { kDatabase, kCommandName, kMetadata, kCommandArgs, kInputDocs, kDone };
-
- virtual ~RequestBuilderInterface() = default;
-
- /**
- * Sets the database that the command will be executed against.
- */
- virtual RequestBuilderInterface& setDatabase(StringData database) = 0;
-
- /**
- * Sets the name of the command to execute.
- */
- virtual RequestBuilderInterface& setCommandName(StringData commandName) = 0;
-
- /**
- * Sets the metadata associated with this command request - see metadata.h for details.
- */
- virtual RequestBuilderInterface& setMetadata(BSONObj metadata) = 0;
-
- /**
- * Sets the arguments to pass to the command.
- */
- virtual RequestBuilderInterface& setCommandArgs(BSONObj commandArgs) = 0;
-
- /**
- * Gets the protocol used to serialize this request. This should only be used for asserts,
- * and not for runtime behavior changes, which should be handled with polymorphism.
- */
- virtual Protocol getProtocol() const = 0;
-
- /**
- * Writes data then transfers ownership of the message to the caller.
- * The behavior of calling any methods on the object is subsequently
- * undefined.
- */
- virtual Message done() = 0;
-
-protected:
- RequestBuilderInterface() = default;
-};
-
-} // namespace rpc
-} // namespace mongo