summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/client/dbclient.cpp12
-rw-r--r--src/mongo/client/dbclientcursor.cpp6
-rw-r--r--src/mongo/db/commands/mr.cpp2
-rw-r--r--src/mongo/db/logical_time_metadata_hook.cpp4
-rw-r--r--src/mongo/db/logical_time_metadata_hook.h6
-rw-r--r--src/mongo/db/pipeline/pipeline_d.cpp7
-rw-r--r--src/mongo/db/s/migration_destination_manager.cpp1
-rw-r--r--src/mongo/db/s/sharded_connection_info.cpp19
-rw-r--r--src/mongo/db/s/sharded_connection_info.h3
-rw-r--r--src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.cpp3
-rw-r--r--src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.h3
-rw-r--r--src/mongo/db/s/sharding_initialization_mongod.cpp2
-rw-r--r--src/mongo/db/s/sharding_state.cpp2
-rw-r--r--src/mongo/executor/network_interface_asio.cpp1
-rw-r--r--src/mongo/executor/network_interface_asio_command.cpp6
-rw-r--r--src/mongo/executor/network_interface_asio_test.cpp6
-rw-r--r--src/mongo/executor/network_interface_mock.cpp2
-rw-r--r--src/mongo/rpc/metadata.h9
-rw-r--r--src/mongo/rpc/metadata/egress_metadata_hook_list.cpp5
-rw-r--r--src/mongo/rpc/metadata/egress_metadata_hook_list.h6
-rw-r--r--src/mongo/rpc/metadata/egress_metadata_hook_list_test.cpp39
-rw-r--r--src/mongo/rpc/metadata/metadata_hook.h8
-rw-r--r--src/mongo/s/client/sharding_connection_hook.cpp12
-rw-r--r--src/mongo/s/client/sharding_connection_hook.h4
-rw-r--r--src/mongo/s/commands/dbclient_multi_command.cpp3
-rw-r--r--src/mongo/s/server.cpp18
-rw-r--r--src/mongo/s/sharding_egress_metadata_hook.cpp22
-rw-r--r--src/mongo/s/sharding_egress_metadata_hook.h24
-rw-r--r--src/mongo/s/sharding_egress_metadata_hook_for_mongos.cpp3
-rw-r--r--src/mongo/s/sharding_egress_metadata_hook_for_mongos.h3
-rw-r--r--src/mongo/s/sharding_test_fixture.cpp5
31 files changed, 130 insertions, 116 deletions
diff --git a/src/mongo/client/dbclient.cpp b/src/mongo/client/dbclient.cpp
index 78c052b01f2..7b252bde560 100644
--- a/src/mongo/client/dbclient.cpp
+++ b/src/mongo/client/dbclient.cpp
@@ -185,8 +185,8 @@ rpc::UniqueReply DBClientWithCommands::runCommandWithMetadata(StringData databas
metadataBob.appendElements(metadata);
if (_metadataWriter) {
- uassertStatusOK(
- _metadataWriter((haveClient() ? cc().getOperationContext() : nullptr), &metadataBob));
+ uassertStatusOK(_metadataWriter(
+ (haveClient() ? cc().getOperationContext() : nullptr), &metadataBob, host));
}
auto requestBuilder = rpc::makeRequestBuilder(getClientRPCProtocols(), getServerRPCProtocols());
@@ -223,16 +223,16 @@ rpc::UniqueReply DBClientWithCommands::runCommandWithMetadata(StringData databas
<< "' ",
requestBuilder->getProtocol() == commandReply->getProtocol());
- if (_metadataReader) {
- uassertStatusOK(_metadataReader(commandReply->getMetadata(), host));
- }
-
if (ErrorCodes::SendStaleConfig ==
getStatusFromCommandResult(commandReply->getCommandReply())) {
throw RecvStaleConfigException("stale config in runCommand",
commandReply->getCommandReply());
}
+ if (_metadataReader) {
+ uassertStatusOK(_metadataReader(commandReply->getMetadata(), host));
+ }
+
return rpc::UniqueReply(std::move(replyMsg), std::move(commandReply));
}
diff --git a/src/mongo/client/dbclientcursor.cpp b/src/mongo/client/dbclientcursor.cpp
index 7a41a85765f..74bd272d147 100644
--- a/src/mongo/client/dbclientcursor.cpp
+++ b/src/mongo/client/dbclientcursor.cpp
@@ -81,8 +81,10 @@ Message assembleCommandRequest(DBClientWithCommands* cli,
BSONObjBuilder metadataBob;
metadataBob.appendElements(upconvertedMetadata);
if (cli->getRequestMetadataWriter()) {
- uassertStatusOK(cli->getRequestMetadataWriter()(
- (haveClient() ? cc().getOperationContext() : nullptr), &metadataBob));
+ uassertStatusOK(
+ cli->getRequestMetadataWriter()((haveClient() ? cc().getOperationContext() : nullptr),
+ &metadataBob,
+ cli->getServerAddress()));
}
requestBuilder->setDatabase(database);
diff --git a/src/mongo/db/commands/mr.cpp b/src/mongo/db/commands/mr.cpp
index d7b8816891f..25e9590a6d9 100644
--- a/src/mongo/db/commands/mr.cpp
+++ b/src/mongo/db/commands/mr.cpp
@@ -1746,6 +1746,8 @@ public:
if (shouldBypassDocumentValidationForCommand(cmdObj))
maybeDisableValidation.emplace(opCtx);
+ ShardedConnectionInfo::addHook();
+
// legacy name
const auto shardedOutputCollectionElt = cmdObj["shardedOutputCollection"];
uassert(ErrorCodes::InvalidNamespace,
diff --git a/src/mongo/db/logical_time_metadata_hook.cpp b/src/mongo/db/logical_time_metadata_hook.cpp
index f45e4fba9db..70acba1de5c 100644
--- a/src/mongo/db/logical_time_metadata_hook.cpp
+++ b/src/mongo/db/logical_time_metadata_hook.cpp
@@ -41,18 +41,20 @@ namespace rpc {
LogicalTimeMetadataHook::LogicalTimeMetadataHook(ServiceContext* service) : _service(service) {}
Status LogicalTimeMetadataHook::writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
BSONObjBuilder* metadataBob) {
LogicalTimeMetadata metadata(LogicalClock::get(_service)->getClusterTime());
metadata.writeToMetadata(metadataBob);
return Status::OK();
}
-Status LogicalTimeMetadataHook::readReplyMetadata(StringData replySource,
+Status LogicalTimeMetadataHook::readReplyMetadata(const HostAndPort& replySource,
const BSONObj& metadataObj) {
auto parseStatus = LogicalTimeMetadata::readFromMetadata(metadataObj);
if (!parseStatus.isOK()) {
return parseStatus.getStatus();
}
+
auto& signedTime = parseStatus.getValue().getSignedTime();
return LogicalClock::get(_service)->advanceClusterTimeFromTrustedSource(signedTime);
}
diff --git a/src/mongo/db/logical_time_metadata_hook.h b/src/mongo/db/logical_time_metadata_hook.h
index 9ca9b0a4625..3fbd2260dd1 100644
--- a/src/mongo/db/logical_time_metadata_hook.h
+++ b/src/mongo/db/logical_time_metadata_hook.h
@@ -48,9 +48,11 @@ class LogicalTimeMetadataHook : public EgressMetadataHook {
public:
explicit LogicalTimeMetadataHook(ServiceContext* service);
- Status writeRequestMetadata(OperationContext* opCtx, BSONObjBuilder* metadataBob) override;
+ Status writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
+ BSONObjBuilder* metadataBob) override;
- Status readReplyMetadata(StringData replySource, const BSONObj& metadataObj) override;
+ Status readReplyMetadata(const HostAndPort& replySource, const BSONObj& metadataObj) override;
private:
ServiceContext* _service;
diff --git a/src/mongo/db/pipeline/pipeline_d.cpp b/src/mongo/db/pipeline/pipeline_d.cpp
index c1d6dc743ac..b976e25f865 100644
--- a/src/mongo/db/pipeline/pipeline_d.cpp
+++ b/src/mongo/db/pipeline/pipeline_d.cpp
@@ -355,6 +355,13 @@ void PipelineD::prepareCursorSource(Collection* collection,
if (!sources.empty()) {
if (sources.front()->isValidInitialSource()) {
+ if (dynamic_cast<DocumentSourceMergeCursors*>(sources.front().get())) {
+ // Enable the hooks for setting up authentication on the subsequent internal
+ // connections we are going to create. This would normally have been done
+ // when SetShardVersion was called, but since SetShardVersion is never called
+ // on secondaries, this is needed.
+ ShardedConnectionInfo::addHook();
+ }
return; // don't need a cursor
}
diff --git a/src/mongo/db/s/migration_destination_manager.cpp b/src/mongo/db/s/migration_destination_manager.cpp
index 8239842289f..470afdd6d02 100644
--- a/src/mongo/db/s/migration_destination_manager.cpp
+++ b/src/mongo/db/s/migration_destination_manager.cpp
@@ -390,6 +390,7 @@ void MigrationDestinationManager::_migrateThread(BSONObj min,
auto opCtx = getGlobalServiceContext()->makeOperationContext(&cc());
if (getGlobalAuthorizationManager()->isAuthEnabled()) {
+ ShardedConnectionInfo::addHook();
AuthorizationSession::get(opCtx->getClient())->grantInternalAuthorization();
}
diff --git a/src/mongo/db/s/sharded_connection_info.cpp b/src/mongo/db/s/sharded_connection_info.cpp
index fea550317aa..336cb68c1ea 100644
--- a/src/mongo/db/s/sharded_connection_info.cpp
+++ b/src/mongo/db/s/sharded_connection_info.cpp
@@ -37,12 +37,9 @@
#include "mongo/client/global_conn_pool.h"
#include "mongo/db/client.h"
-#include "mongo/db/logical_time_metadata_hook.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/s/sharding_egress_metadata_hook_for_mongod.h"
-#include "mongo/db/service_context.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/rpc/metadata/egress_metadata_hook_list.h"
#include "mongo/s/chunk_version.h"
#include "mongo/s/client/shard_connection.h"
#include "mongo/s/client/sharding_connection_hook.h"
@@ -94,7 +91,7 @@ void ShardedConnectionInfo::setVersion(const std::string& ns, const ChunkVersion
_versions[ns] = version;
}
-void ShardedConnectionInfo::addHook(ServiceContext* service) {
+void ShardedConnectionInfo::addHook() {
if (alreadyAddedHook.loadRelaxed()) {
return;
}
@@ -107,17 +104,11 @@ void ShardedConnectionInfo::addHook(ServiceContext* service) {
log() << "first cluster operation detected, adding sharding hook to enable versioning "
"and authentication to remote servers";
- auto unshardedHookList = stdx::make_unique<rpc::EgressMetadataHookList>();
- unshardedHookList->addHook(stdx::make_unique<rpc::LogicalTimeMetadataHook>(service));
- unshardedHookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongod>(false));
+ globalConnPool.addHook(new ShardingConnectionHook(
+ false, stdx::make_unique<rpc::ShardingEgressMetadataHookForMongod>()));
- globalConnPool.addHook(new ShardingConnectionHook(false, std::move(unshardedHookList)));
-
- auto shardedHookList = stdx::make_unique<rpc::EgressMetadataHookList>();
- shardedHookList->addHook(stdx::make_unique<rpc::LogicalTimeMetadataHook>(service));
- shardedHookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongod>(true));
-
- shardConnectionPool.addHook(new ShardingConnectionHook(true, std::move(shardedHookList)));
+ shardConnectionPool.addHook(new ShardingConnectionHook(
+ true, stdx::make_unique<rpc::ShardingEgressMetadataHookForMongod>()));
alreadyAddedHook.store(1);
}
diff --git a/src/mongo/db/s/sharded_connection_info.h b/src/mongo/db/s/sharded_connection_info.h
index 9efc734fe2c..4cfae41c263 100644
--- a/src/mongo/db/s/sharded_connection_info.h
+++ b/src/mongo/db/s/sharded_connection_info.h
@@ -37,7 +37,6 @@ namespace mongo {
struct ChunkVersion;
class Client;
-class ServiceContext;
/**
* There is one instance of these per each connection from mongos. Holds version state for each
@@ -64,7 +63,7 @@ public:
void setVersion(const std::string& ns, const ChunkVersion& version);
static void reset(Client* client);
- static void addHook(ServiceContext* service);
+ static void addHook();
private:
typedef std::map<std::string, ChunkVersion> NSVersionMap;
diff --git a/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.cpp b/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.cpp
index 24295466ed9..99603ce0ed4 100644
--- a/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.cpp
+++ b/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.cpp
@@ -40,9 +40,6 @@
namespace mongo {
namespace rpc {
-ShardingEgressMetadataHookForMongod::ShardingEgressMetadataHookForMongod(bool shardedConnection)
- : ShardingEgressMetadataHook(shardedConnection) {}
-
void ShardingEgressMetadataHookForMongod::_saveGLEStats(const BSONObj& metadata,
StringData hostString) {}
diff --git a/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.h b/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.h
index 3c07f847f72..f9032ef6945 100644
--- a/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.h
+++ b/src/mongo/db/s/sharding_egress_metadata_hook_for_mongod.h
@@ -34,9 +34,6 @@ namespace mongo {
namespace rpc {
class ShardingEgressMetadataHookForMongod final : public ShardingEgressMetadataHook {
-public:
- ShardingEgressMetadataHookForMongod(bool shardedConnection);
-
private:
void _saveGLEStats(const BSONObj& metadata, StringData hostString) override;
diff --git a/src/mongo/db/s/sharding_initialization_mongod.cpp b/src/mongo/db/s/sharding_initialization_mongod.cpp
index 2e536dbbb0b..b329a325423 100644
--- a/src/mongo/db/s/sharding_initialization_mongod.cpp
+++ b/src/mongo/db/s/sharding_initialization_mongod.cpp
@@ -92,7 +92,7 @@ Status initializeGlobalShardingStateForMongod(OperationContext* opCtx,
auto hookList = stdx::make_unique<rpc::EgressMetadataHookList>();
hookList->addHook(
stdx::make_unique<rpc::LogicalTimeMetadataHook>(opCtx->getServiceContext()));
- hookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongod>(false));
+ hookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongod>());
return hookList;
},
[](ShardingCatalogClient* catalogClient, std::unique_ptr<executor::TaskExecutor> executor)
diff --git a/src/mongo/db/s/sharding_state.cpp b/src/mongo/db/s/sharding_state.cpp
index 5bbb6d9c925..567877c216a 100644
--- a/src/mongo/db/s/sharding_state.cpp
+++ b/src/mongo/db/s/sharding_state.cpp
@@ -357,7 +357,7 @@ Status ShardingState::initializeFromShardIdentity(OperationContext* opCtx,
<< causedBy(_initializationStatus)};
}
- ShardedConnectionInfo::addHook(opCtx->getServiceContext());
+ ShardedConnectionInfo::addHook();
try {
Status status = _globalInit(opCtx, configSvrConnStr, generateDistLockProcessId(opCtx));
diff --git a/src/mongo/executor/network_interface_asio.cpp b/src/mongo/executor/network_interface_asio.cpp
index d60bc787731..8fb4733bbb6 100644
--- a/src/mongo/executor/network_interface_asio.cpp
+++ b/src/mongo/executor/network_interface_asio.cpp
@@ -233,6 +233,7 @@ Status attachMetadataIfNeeded(RemoteCommandRequest& request,
auto writeStatus = callNoexcept(*metadataHook,
&rpc::EgressMetadataHook::writeRequestMetadata,
request.opCtx,
+ request.target,
&augmentedBob);
if (!writeStatus.isOK()) {
return writeStatus;
diff --git a/src/mongo/executor/network_interface_asio_command.cpp b/src/mongo/executor/network_interface_asio_command.cpp
index 9498c292b22..c72a7b74505 100644
--- a/src/mongo/executor/network_interface_asio_command.cpp
+++ b/src/mongo/executor/network_interface_asio_command.cpp
@@ -159,10 +159,8 @@ ResponseStatus decodeRPC(Message* received,
// Handle incoming reply metadata.
if (metadataHook) {
- auto listenStatus = callNoexcept(*metadataHook,
- &rpc::EgressMetadataHook::readReplyMetadata,
- source.toString(),
- replyMetadata);
+ auto listenStatus = callNoexcept(
+ *metadataHook, &rpc::EgressMetadataHook::readReplyMetadata, source, replyMetadata);
if (!listenStatus.isOK()) {
return {listenStatus, elapsed};
}
diff --git a/src/mongo/executor/network_interface_asio_test.cpp b/src/mongo/executor/network_interface_asio_test.cpp
index 1f14d4063f5..f7e6d4a091e 100644
--- a/src/mongo/executor/network_interface_asio_test.cpp
+++ b/src/mongo/executor/network_interface_asio_test.cpp
@@ -988,13 +988,15 @@ public:
TestMetadataHook(bool* wroteRequestMetadata, bool* gotReplyMetadata)
: _wroteRequestMetadata(wroteRequestMetadata), _gotReplyMetadata(gotReplyMetadata) {}
- Status writeRequestMetadata(OperationContext* opCtx, BSONObjBuilder* metadataBob) override {
+ Status writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
+ BSONObjBuilder* metadataBob) override {
metadataBob->append("foo", "bar");
*_wroteRequestMetadata = true;
return Status::OK();
}
- Status readReplyMetadata(StringData replySource, const BSONObj& metadataObj) override {
+ Status readReplyMetadata(const HostAndPort& replySource, const BSONObj& metadataObj) override {
*_gotReplyMetadata = (metadataObj["baz"].str() == "garply");
return Status::OK();
}
diff --git a/src/mongo/executor/network_interface_mock.cpp b/src/mongo/executor/network_interface_mock.cpp
index 81198e74ee2..8a0c44d90fc 100644
--- a/src/mongo/executor/network_interface_mock.cpp
+++ b/src/mongo/executor/network_interface_mock.cpp
@@ -302,7 +302,7 @@ void NetworkInterfaceMock::scheduleResponse(NetworkOperationIterator noi,
// If no RemoteCommandResponse was returned (for example, on a simulated network error), then
// do not attempt to run the metadata hook, since there is no returned metadata.
if (_metadataHook && response.isOK()) {
- _metadataHook->readReplyMetadata(noi->getRequest().target.toString(), response.metadata);
+ _metadataHook->readReplyMetadata(noi->getRequest().target, response.metadata);
}
noi->setResponse(when, response);
diff --git a/src/mongo/rpc/metadata.h b/src/mongo/rpc/metadata.h
index 42c10bb3d24..d8956de30f7 100644
--- a/src/mongo/rpc/metadata.h
+++ b/src/mongo/rpc/metadata.h
@@ -104,11 +104,11 @@ StatusWith<BSONObj> downconvertReplyMetadata(const BSONObj& commandReply,
/**
* A function type for writing request metadata. The function takes a pointer to an optional
* OperationContext so metadata associated with a Client can be appended, a pointer to a
- * BSONObjBuilder used to construct the metadata object and returns a Status indicating if the
- * metadata was written successfully.
+ * BSONObjBuilder used to construct the metadata object and the server address of the target of the
+ * request and returns a Status indicating if the metadata was written successfully.
*/
using RequestMetadataWriter =
- stdx::function<Status(OperationContext* opCtx, BSONObjBuilder* metadataBuilder)>;
+ stdx::function<Status(OperationContext*, BSONObjBuilder*, StringData)>;
/**
* A function type for reading reply metadata. The function takes a a reference to a
@@ -118,8 +118,7 @@ using RequestMetadataWriter =
*
* TODO: would it be a layering violation if this hook took an OperationContext* ?
*/
-using ReplyMetadataReader =
- stdx::function<Status(const BSONObj& replyMetadata, StringData sourceHost)>;
+using ReplyMetadataReader = stdx::function<Status(const BSONObj&, StringData)>;
} // namespace rpc
} // namespace mongo
diff --git a/src/mongo/rpc/metadata/egress_metadata_hook_list.cpp b/src/mongo/rpc/metadata/egress_metadata_hook_list.cpp
index 2c2ae6d3349..5e11c84eb60 100644
--- a/src/mongo/rpc/metadata/egress_metadata_hook_list.cpp
+++ b/src/mongo/rpc/metadata/egress_metadata_hook_list.cpp
@@ -41,9 +41,10 @@ void EgressMetadataHookList::addHook(std::unique_ptr<EgressMetadataHook>&& newHo
}
Status EgressMetadataHookList::writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
BSONObjBuilder* metadataBob) {
for (auto&& hook : _hooks) {
- auto status = hook->writeRequestMetadata(opCtx, metadataBob);
+ auto status = hook->writeRequestMetadata(opCtx, requestDestination, metadataBob);
if (!status.isOK()) {
return status;
}
@@ -52,7 +53,7 @@ Status EgressMetadataHookList::writeRequestMetadata(OperationContext* opCtx,
return Status::OK();
}
-Status EgressMetadataHookList::readReplyMetadata(StringData replySource,
+Status EgressMetadataHookList::readReplyMetadata(const HostAndPort& replySource,
const BSONObj& metadataObj) {
for (auto&& hook : _hooks) {
auto status = hook->readReplyMetadata(replySource, metadataObj);
diff --git a/src/mongo/rpc/metadata/egress_metadata_hook_list.h b/src/mongo/rpc/metadata/egress_metadata_hook_list.h
index 64087bc0e25..54b03b80c5e 100644
--- a/src/mongo/rpc/metadata/egress_metadata_hook_list.h
+++ b/src/mongo/rpc/metadata/egress_metadata_hook_list.h
@@ -58,14 +58,16 @@ public:
* early if one of hooks returned a non OK status and return it. Note that metadataBob should
* not be used if Status is not OK as the contents can be partial.
*/
- Status writeRequestMetadata(OperationContext* opCtx, BSONObjBuilder* metadataBob) override;
+ Status writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
+ BSONObjBuilder* metadataBob) override;
/**
* Calls readReplyMetadata on every hook in the order they were added. This will terminate
* early if one of hooks returned a non OK status and return it. Note that metadataBob should
* not be used if Status is not OK as the contents can be partial.
*/
- Status readReplyMetadata(StringData replySource, const BSONObj& metadataObj) override;
+ Status readReplyMetadata(const HostAndPort& replySource, const BSONObj& metadataObj) override;
private:
std::vector<std::unique_ptr<EgressMetadataHook>> _hooks;
diff --git a/src/mongo/rpc/metadata/egress_metadata_hook_list_test.cpp b/src/mongo/rpc/metadata/egress_metadata_hook_list_test.cpp
index 63293347428..159a78412fb 100644
--- a/src/mongo/rpc/metadata/egress_metadata_hook_list_test.cpp
+++ b/src/mongo/rpc/metadata/egress_metadata_hook_list_test.cpp
@@ -43,7 +43,7 @@ namespace {
struct ReadReplyArgs {
public:
- StringData replySource;
+ HostAndPort replySource;
BSONObj metadataObj;
};
@@ -51,12 +51,14 @@ class TestHook : public EgressMetadataHook {
public:
TestHook(string fieldName, ReadReplyArgs* arg) : _fieldName(fieldName), _arg(arg) {}
- Status writeRequestMetadata(OperationContext* opCtx, BSONObjBuilder* metadataBob) override {
- metadataBob->append(_fieldName, "");
+ Status writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
+ BSONObjBuilder* metadataBob) override {
+ metadataBob->append(_fieldName, requestDestination.toString());
return Status::OK();
}
- Status readReplyMetadata(StringData replySource, const BSONObj& metadataObj) {
+ Status readReplyMetadata(const HostAndPort& replySource, const BSONObj& metadataObj) {
invariant(_arg != nullptr);
_arg->replySource = replySource;
_arg->metadataObj = metadataObj;
@@ -72,11 +74,13 @@ class FixedStatusTestHook : public EgressMetadataHook {
public:
FixedStatusTestHook(Status status) : _toRet(status) {}
- Status writeRequestMetadata(OperationContext* opCtx, BSONObjBuilder* metadataBob) override {
+ Status writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
+ BSONObjBuilder* metadataBob) override {
return _toRet;
}
- Status readReplyMetadata(StringData replySource, const BSONObj& metadataObj) {
+ Status readReplyMetadata(const HostAndPort& replySource, const BSONObj& metadataObj) {
return _toRet;
}
@@ -86,10 +90,11 @@ private:
TEST(EgressMetadataHookListTest, EmptyHookShouldNotFail) {
EgressMetadataHookList hookList;
- ASSERT_OK(hookList.writeRequestMetadata(nullptr, nullptr));
+ HostAndPort emptyHost;
+ ASSERT_OK(hookList.writeRequestMetadata(nullptr, emptyHost, nullptr));
BSONObj emptyObj;
- ASSERT_OK(hookList.readReplyMetadata("", emptyObj));
+ ASSERT_OK(hookList.readReplyMetadata(emptyHost, emptyObj));
}
TEST(EgressMetadataHookListTest, SingleHook) {
@@ -99,12 +104,12 @@ TEST(EgressMetadataHookListTest, SingleHook) {
hookList.addHook(std::move(hook1));
BSONObjBuilder builder;
- ASSERT_OK(hookList.writeRequestMetadata(nullptr, &builder));
+ ASSERT_OK(hookList.writeRequestMetadata(nullptr, HostAndPort("a:123"), &builder));
ASSERT_BSONOBJ_EQ(BSON("h1"
- << ""),
+ << "a:123"),
builder.obj());
- string testHost("b:456");
+ HostAndPort testHost("b:456");
BSONObj testObj(BSON("x" << 1));
ASSERT_OK(hookList.readReplyMetadata(testHost, testObj));
ASSERT_EQ(testHost, hook1Args.replySource);
@@ -122,14 +127,14 @@ TEST(EgressMetadataHookListTest, MultipleHooks) {
hookList.addHook(std::move(hook2));
BSONObjBuilder builder;
- ASSERT_OK(hookList.writeRequestMetadata(nullptr, &builder));
+ ASSERT_OK(hookList.writeRequestMetadata(nullptr, HostAndPort("a:123"), &builder));
ASSERT_BSONOBJ_EQ(BSON("foo"
- << ""
+ << "a:123"
<< "bar"
- << ""),
+ << "a:123"),
builder.obj());
- string testHost("b:456");
+ HostAndPort testHost("b:456");
BSONObj testObj(BSON("x" << 1));
ASSERT_OK(hookList.readReplyMetadata(testHost, testObj));
@@ -151,8 +156,8 @@ TEST(EgressMetadataHookListTest, SingleBadHookShouldReturnError) {
hookList.addHook(std::move(hook2));
BSONObjBuilder builder;
- ASSERT_NOT_OK(hookList.writeRequestMetadata(nullptr, &builder));
- ASSERT_NOT_OK(hookList.readReplyMetadata("b:456", BSON("x" << 1)));
+ ASSERT_NOT_OK(hookList.writeRequestMetadata(nullptr, HostAndPort("a:123"), &builder));
+ ASSERT_NOT_OK(hookList.readReplyMetadata(HostAndPort("b:456"), BSON("x" << 1)));
}
} // unnamed namespace
diff --git a/src/mongo/rpc/metadata/metadata_hook.h b/src/mongo/rpc/metadata/metadata_hook.h
index 1bb050e0eda..81f0001f548 100644
--- a/src/mongo/rpc/metadata/metadata_hook.h
+++ b/src/mongo/rpc/metadata/metadata_hook.h
@@ -35,7 +35,6 @@ class BSONObjBuilder;
struct HostAndPort;
class OperationContext;
class Status;
-class StringData;
namespace rpc {
@@ -59,13 +58,16 @@ public:
* not
* have an OperationContext as a result.
*/
- virtual Status writeRequestMetadata(OperationContext* opCtx, BSONObjBuilder* metadataBob) = 0;
+ virtual Status writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& requestDestination,
+ BSONObjBuilder* metadataBob) = 0;
/**
* Reads metadata from an incoming command reply. This method must not throw or block on
* database or network operations and can be called by multiple concurrent threads.
*/
- virtual Status readReplyMetadata(StringData replySource, const BSONObj& metadataObj) = 0;
+ virtual Status readReplyMetadata(const HostAndPort& replySource,
+ const BSONObj& metadataObj) = 0;
protected:
EgressMetadataHook() = default;
diff --git a/src/mongo/s/client/sharding_connection_hook.cpp b/src/mongo/s/client/sharding_connection_hook.cpp
index 057a9de1c4d..36cb24bf9fc 100644
--- a/src/mongo/s/client/sharding_connection_hook.cpp
+++ b/src/mongo/s/client/sharding_connection_hook.cpp
@@ -48,8 +48,8 @@ namespace mongo {
using std::string;
-ShardingConnectionHook::ShardingConnectionHook(bool shardedConnections,
- std::unique_ptr<rpc::EgressMetadataHook> egressHook)
+ShardingConnectionHook::ShardingConnectionHook(
+ bool shardedConnections, std::unique_ptr<rpc::ShardingEgressMetadataHook> egressHook)
: _shardedConnections(shardedConnections), _egressHook(std::move(egressHook)) {}
void ShardingConnectionHook::onCreate(DBClientBase* conn) {
@@ -77,9 +77,11 @@ void ShardingConnectionHook::onCreate(DBClientBase* conn) {
return _egressHook->readReplyMetadata(target, metadataObj);
});
}
- conn->setRequestMetadataWriter([this](OperationContext* opCtx, BSONObjBuilder* metadataBob) {
- return _egressHook->writeRequestMetadata(opCtx, metadataBob);
- });
+ conn->setRequestMetadataWriter(
+ [this](OperationContext* opCtx, BSONObjBuilder* metadataBob, StringData hostStringData) {
+ return _egressHook->writeRequestMetadata(
+ _shardedConnections, opCtx, hostStringData, metadataBob);
+ });
if (conn->type() == ConnectionString::MASTER) {
diff --git a/src/mongo/s/client/sharding_connection_hook.h b/src/mongo/s/client/sharding_connection_hook.h
index c344a0ba6cb..02c300b026b 100644
--- a/src/mongo/s/client/sharding_connection_hook.h
+++ b/src/mongo/s/client/sharding_connection_hook.h
@@ -43,7 +43,7 @@ class DBClientBase;
class ShardingConnectionHook : public DBConnectionHook {
public:
ShardingConnectionHook(bool shardedConnections,
- std::unique_ptr<rpc::EgressMetadataHook> egressHook);
+ std::unique_ptr<rpc::ShardingEgressMetadataHook> egressHook);
void onCreate(DBClientBase* conn) override;
void onDestroy(DBClientBase* conn) override;
@@ -54,7 +54,7 @@ private:
// Use the implementation of the metadata readers and writers in ShardingEgressMetadataHook,
// since that is the hook for Network Interface ASIO and this hook is to be deprecated.
- std::unique_ptr<rpc::EgressMetadataHook> _egressHook;
+ std::unique_ptr<rpc::ShardingEgressMetadataHook> _egressHook;
};
} // namespace mongo
diff --git a/src/mongo/s/commands/dbclient_multi_command.cpp b/src/mongo/s/commands/dbclient_multi_command.cpp
index 131c40d0b13..2bceb5a4993 100644
--- a/src/mongo/s/commands/dbclient_multi_command.cpp
+++ b/src/mongo/s/commands/dbclient_multi_command.cpp
@@ -90,7 +90,8 @@ static void sayAsCmd(DBClientBase* conn, StringData dbName, const BSONObj& cmdOb
metadataBob.appendElements(upconvertedMetadata);
if (conn->getRequestMetadataWriter()) {
conn->getRequestMetadataWriter()((haveClient() ? cc().getOperationContext() : nullptr),
- &metadataBob);
+ &metadataBob,
+ conn->getServerAddress());
}
requestBuilder->setDatabase(dbName);
diff --git a/src/mongo/s/server.cpp b/src/mongo/s/server.cpp
index d3a797b3a49..bd177748fcf 100644
--- a/src/mongo/s/server.cpp
+++ b/src/mongo/s/server.cpp
@@ -207,7 +207,7 @@ static Status initializeSharding(OperationContext* opCtx) {
auto hookList = stdx::make_unique<rpc::EgressMetadataHookList>();
hookList->addHook(
stdx::make_unique<rpc::LogicalTimeMetadataHook>(opCtx->getServiceContext()));
- hookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongos>(false));
+ hookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongos>());
return hookList;
},
[](ShardingCatalogClient* catalogClient, std::unique_ptr<executor::TaskExecutor> executor) {
@@ -257,20 +257,12 @@ static ExitCode runMongosServer() {
return EXIT_NET_ERROR;
}
- auto unshardedHookList = stdx::make_unique<rpc::EgressMetadataHookList>();
- unshardedHookList->addHook(
- stdx::make_unique<rpc::LogicalTimeMetadataHook>(getGlobalServiceContext()));
- unshardedHookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongos>(false));
-
// Add sharding hooks to both connection pools - ShardingConnectionHook includes auth hooks
- globalConnPool.addHook(new ShardingConnectionHook(false, std::move(unshardedHookList)));
-
- auto shardedHookList = stdx::make_unique<rpc::EgressMetadataHookList>();
- shardedHookList->addHook(
- stdx::make_unique<rpc::LogicalTimeMetadataHook>(getGlobalServiceContext()));
- shardedHookList->addHook(stdx::make_unique<rpc::ShardingEgressMetadataHookForMongos>(true));
+ globalConnPool.addHook(new ShardingConnectionHook(
+ false, stdx::make_unique<rpc::ShardingEgressMetadataHookForMongos>()));
- shardConnectionPool.addHook(new ShardingConnectionHook(true, std::move(shardedHookList)));
+ shardConnectionPool.addHook(new ShardingConnectionHook(
+ true, stdx::make_unique<rpc::ShardingEgressMetadataHookForMongos>()));
ReplicaSetMonitor::setAsynchronousConfigChangeHook(
&ShardRegistry::replicaSetChangeConfigServerUpdateHook);
diff --git a/src/mongo/s/sharding_egress_metadata_hook.cpp b/src/mongo/s/sharding_egress_metadata_hook.cpp
index cc4823a3384..af263360a0d 100644
--- a/src/mongo/s/sharding_egress_metadata_hook.cpp
+++ b/src/mongo/s/sharding_egress_metadata_hook.cpp
@@ -50,16 +50,15 @@ namespace rpc {
using std::shared_ptr;
-ShardingEgressMetadataHook::ShardingEgressMetadataHook(bool shardedConnection)
- : _isShardedConnection(shardedConnection) {}
-
-Status ShardingEgressMetadataHook::writeRequestMetadata(OperationContext* opCtx,
+Status ShardingEgressMetadataHook::writeRequestMetadata(bool shardedConnection,
+ OperationContext* opCtx,
+ const StringData target,
BSONObjBuilder* metadataBob) {
try {
audit::writeImpersonatedUsersToMetadata(opCtx, metadataBob);
ClientMetadataIsMasterState::writeToMetadata(opCtx, metadataBob);
- if (!_isShardedConnection) {
+ if (!shardedConnection) {
return Status::OK();
}
rpc::ConfigServerMetadata(_getConfigServerOpTime()).writeToMetadata(metadataBob);
@@ -69,7 +68,13 @@ Status ShardingEgressMetadataHook::writeRequestMetadata(OperationContext* opCtx,
}
}
-Status ShardingEgressMetadataHook::readReplyMetadata(StringData replySource,
+Status ShardingEgressMetadataHook::writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& target,
+ BSONObjBuilder* metadataBob) {
+ return writeRequestMetadata(true, opCtx, target.toString(), metadataBob);
+}
+
+Status ShardingEgressMetadataHook::readReplyMetadata(const StringData replySource,
const BSONObj& metadataObj) {
try {
_saveGLEStats(metadataObj, replySource);
@@ -79,6 +84,11 @@ Status ShardingEgressMetadataHook::readReplyMetadata(StringData replySource,
}
}
+Status ShardingEgressMetadataHook::readReplyMetadata(const HostAndPort& replySource,
+ const BSONObj& metadataObj) {
+ return readReplyMetadata(replySource.toString(), metadataObj);
+}
+
Status ShardingEgressMetadataHook::_advanceConfigOptimeFromShard(ShardId shardId,
const BSONObj& metadataObj) {
try {
diff --git a/src/mongo/s/sharding_egress_metadata_hook.h b/src/mongo/s/sharding_egress_metadata_hook.h
index 87442ebe0f3..1c8849dcea3 100644
--- a/src/mongo/s/sharding_egress_metadata_hook.h
+++ b/src/mongo/s/sharding_egress_metadata_hook.h
@@ -43,14 +43,23 @@ namespace rpc {
class ShardingEgressMetadataHook : public rpc::EgressMetadataHook {
public:
- /**
- * Pass true to shardedConnection if the hook is intended for connections with shard versions.
- */
- ShardingEgressMetadataHook(bool shardedConnection);
virtual ~ShardingEgressMetadataHook() = default;
- Status readReplyMetadata(StringData replySource, const BSONObj& metadataObj) override;
- Status writeRequestMetadata(OperationContext* opCtx, BSONObjBuilder* metadataBob) override;
+ Status readReplyMetadata(const HostAndPort& replySource, const BSONObj& metadataObj) override;
+ Status writeRequestMetadata(OperationContext* opCtx,
+ const HostAndPort& target,
+ BSONObjBuilder* metadataBob) override;
+
+ // These overloaded methods exist to allow ShardingConnectionHook, which is soon to be
+ // deprecated, to use the logic in ShardingEgressMetadataHook instead of duplicating the
+ // logic. ShardingConnectionHook must provide the replySource and target as strings rather than
+ // HostAndPorts, since DBClientReplicaSet uses the hook before it decides on the actual host to
+ // contact.
+ Status readReplyMetadata(const StringData replySource, const BSONObj& metadataObj);
+ Status writeRequestMetadata(bool shardedConnection,
+ OperationContext* opCtx,
+ const StringData target,
+ BSONObjBuilder* metadataBob);
protected:
/**
@@ -74,9 +83,6 @@ protected:
* metadata in the response object from running a command.
*/
virtual Status _advanceConfigOptimeFromShard(ShardId shardId, const BSONObj& metadataObj);
-
-private:
- bool _isShardedConnection;
};
} // namespace rpc
diff --git a/src/mongo/s/sharding_egress_metadata_hook_for_mongos.cpp b/src/mongo/s/sharding_egress_metadata_hook_for_mongos.cpp
index 1ae82a7c64e..f355054f92b 100644
--- a/src/mongo/s/sharding_egress_metadata_hook_for_mongos.cpp
+++ b/src/mongo/s/sharding_egress_metadata_hook_for_mongos.cpp
@@ -41,9 +41,6 @@
namespace mongo {
namespace rpc {
-ShardingEgressMetadataHookForMongos::ShardingEgressMetadataHookForMongos(bool shardedConnection)
- : ShardingEgressMetadataHook(shardedConnection) {}
-
void ShardingEgressMetadataHookForMongos::_saveGLEStats(const BSONObj& metadata,
StringData hostString) {
if (!haveClient()) {
diff --git a/src/mongo/s/sharding_egress_metadata_hook_for_mongos.h b/src/mongo/s/sharding_egress_metadata_hook_for_mongos.h
index 2e5bfe62434..9cba4226df2 100644
--- a/src/mongo/s/sharding_egress_metadata_hook_for_mongos.h
+++ b/src/mongo/s/sharding_egress_metadata_hook_for_mongos.h
@@ -34,9 +34,6 @@ namespace mongo {
namespace rpc {
class ShardingEgressMetadataHookForMongos final : public ShardingEgressMetadataHook {
-public:
- ShardingEgressMetadataHookForMongos(bool shardedConnection);
-
private:
void _saveGLEStats(const BSONObj& metadata, StringData hostString) override;
diff --git a/src/mongo/s/sharding_test_fixture.cpp b/src/mongo/s/sharding_test_fixture.cpp
index 4068545c113..59d3762925f 100644
--- a/src/mongo/s/sharding_test_fixture.cpp
+++ b/src/mongo/s/sharding_test_fixture.cpp
@@ -108,15 +108,14 @@ void ShardingTestFixture::setUp() {
// Set up executor pool used for most operations.
auto fixedNet = stdx::make_unique<executor::NetworkInterfaceMock>();
- fixedNet->setEgressMetadataHook(stdx::make_unique<ShardingEgressMetadataHookForMongos>(false));
+ fixedNet->setEgressMetadataHook(stdx::make_unique<ShardingEgressMetadataHookForMongos>());
_mockNetwork = fixedNet.get();
auto fixedExec = makeThreadPoolTestExecutor(std::move(fixedNet));
_networkTestEnv = stdx::make_unique<NetworkTestEnv>(fixedExec.get(), _mockNetwork);
_executor = fixedExec.get();
auto netForPool = stdx::make_unique<executor::NetworkInterfaceMock>();
- netForPool->setEgressMetadataHook(
- stdx::make_unique<ShardingEgressMetadataHookForMongos>(false));
+ netForPool->setEgressMetadataHook(stdx::make_unique<ShardingEgressMetadataHookForMongos>());
auto execForPool = makeThreadPoolTestExecutor(std::move(netForPool));
std::vector<std::unique_ptr<executor::TaskExecutor>> executorsForPool;
executorsForPool.emplace_back(std::move(execForPool));