summaryrefslogtreecommitdiff
path: root/src/mongo/s
diff options
context:
space:
mode:
authorXueruiFa <xuerui.fa@mongodb.com>2020-07-16 18:03:11 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-07-29 15:23:07 +0000
commit7b910aba3c500839692d142b4c64560b1fc2f29b (patch)
treef56189478f203aac17cbe9d10bf91b1969653155 /src/mongo/s
parent4b880132b11c16a4a0cba4e5c3ce77892dd01f7c (diff)
downloadmongo-7b910aba3c500839692d142b4c64560b1fc2f29b.tar.gz
SERVER-49376: Ensure cursors inherit API settings of the initiating command
Diffstat (limited to 'src/mongo/s')
-rw-r--r--src/mongo/s/query/SConscript3
-rw-r--r--src/mongo/s/query/cluster_aggregation_planner.cpp6
-rw-r--r--src/mongo/s/query/cluster_client_cursor.h6
-rw-r--r--src/mongo/s/query/cluster_client_cursor_impl.cpp4
-rw-r--r--src/mongo/s/query/cluster_client_cursor_impl.h2
-rw-r--r--src/mongo/s/query/cluster_client_cursor_impl_test.cpp27
-rw-r--r--src/mongo/s/query/cluster_client_cursor_mock.cpp8
-rw-r--r--src/mongo/s/query/cluster_client_cursor_mock.h6
-rw-r--r--src/mongo/s/query/cluster_client_cursor_params.h7
-rw-r--r--src/mongo/s/query/cluster_cursor_manager_test.cpp26
-rw-r--r--src/mongo/s/query/cluster_find.cpp5
-rw-r--r--src/mongo/s/query/store_possible_cursor.cpp6
12 files changed, 96 insertions, 10 deletions
diff --git a/src/mongo/s/query/SConscript b/src/mongo/s/query/SConscript
index 0b924534119..05daa81d443 100644
--- a/src/mongo/s/query/SConscript
+++ b/src/mongo/s/query/SConscript
@@ -47,6 +47,7 @@ env.Library(
"cluster_client_cursor_impl.cpp",
],
LIBDEPS=[
+ '$BUILD_DIR/mongo/db/shared_request_handling',
"router_exec_stage",
],
)
@@ -93,6 +94,7 @@ env.Library(
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/db/shared_request_handling',
],
)
@@ -123,6 +125,7 @@ env.Library(
'$BUILD_DIR/mongo/db/kill_sessions',
'$BUILD_DIR/mongo/db/logical_session_cache',
'$BUILD_DIR/mongo/db/logical_session_id',
+ '$BUILD_DIR/mongo/db/shared_request_handling',
],
)
diff --git a/src/mongo/s/query/cluster_aggregation_planner.cpp b/src/mongo/s/query/cluster_aggregation_planner.cpp
index 8271c404702..6632dee755a 100644
--- a/src/mongo/s/query/cluster_aggregation_planner.cpp
+++ b/src/mongo/s/query/cluster_aggregation_planner.cpp
@@ -250,8 +250,10 @@ BSONObj establishMergingMongosCursor(OperationContext* opCtx,
std::unique_ptr<Pipeline, PipelineDeleter> pipelineForMerging,
const PrivilegeVector& privileges) {
- ClusterClientCursorParams params(
- requestedNss, ReadPreferenceSetting::get(opCtx), ReadConcernArgs::get(opCtx));
+ ClusterClientCursorParams params(requestedNss,
+ APIParameters::get(opCtx),
+ ReadPreferenceSetting::get(opCtx),
+ ReadConcernArgs::get(opCtx));
params.originatingCommandObj = CurOp::get(opCtx)->opDescription().getOwned();
params.tailableMode = pipelineForMerging->getContext()->tailableMode;
diff --git a/src/mongo/s/query/cluster_client_cursor.h b/src/mongo/s/query/cluster_client_cursor.h
index 6dc1ae8419e..44aae05e34d 100644
--- a/src/mongo/s/query/cluster_client_cursor.h
+++ b/src/mongo/s/query/cluster_client_cursor.h
@@ -33,6 +33,7 @@
#include "mongo/client/read_preference.h"
#include "mongo/db/auth/user_name.h"
+#include "mongo/db/initialize_api_parameters.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/logical_session_id.h"
#include "mongo/s/query/cluster_client_cursor_params.h"
@@ -176,6 +177,11 @@ public:
virtual boost::optional<TxnNumber> getTxnNumber() const = 0;
/**
+ * Returns the APIParameters for this cursor.
+ */
+ virtual APIParameters getAPIParameters() const = 0;
+
+ /**
* Returns the readPreference for this cursor.
*/
virtual boost::optional<ReadPreferenceSetting> getReadPreference() const = 0;
diff --git a/src/mongo/s/query/cluster_client_cursor_impl.cpp b/src/mongo/s/query/cluster_client_cursor_impl.cpp
index fefd913f8a7..d0cc5fd88b2 100644
--- a/src/mongo/s/query/cluster_client_cursor_impl.cpp
+++ b/src/mongo/s/query/cluster_client_cursor_impl.cpp
@@ -205,6 +205,10 @@ void ClusterClientCursorImpl::incNBatches() {
++_nBatchesReturned;
}
+APIParameters ClusterClientCursorImpl::getAPIParameters() const {
+ return _params.apiParameters;
+}
+
boost::optional<ReadPreferenceSetting> ClusterClientCursorImpl::getReadPreference() const {
return _params.readPreference;
}
diff --git a/src/mongo/s/query/cluster_client_cursor_impl.h b/src/mongo/s/query/cluster_client_cursor_impl.h
index 23f1c351fda..e3a853db464 100644
--- a/src/mongo/s/query/cluster_client_cursor_impl.h
+++ b/src/mongo/s/query/cluster_client_cursor_impl.h
@@ -102,6 +102,8 @@ public:
boost::optional<TxnNumber> getTxnNumber() const final;
+ APIParameters getAPIParameters() const final;
+
boost::optional<ReadPreferenceSetting> getReadPreference() const final;
boost::optional<ReadConcernArgs> getReadConcern() const final;
diff --git a/src/mongo/s/query/cluster_client_cursor_impl_test.cpp b/src/mongo/s/query/cluster_client_cursor_impl_test.cpp
index 0119abcbd68..630182bda5f 100644
--- a/src/mongo/s/query/cluster_client_cursor_impl_test.cpp
+++ b/src/mongo/s/query/cluster_client_cursor_impl_test.cpp
@@ -56,10 +56,11 @@ TEST_F(ClusterClientCursorImplTest, NumReturnedSoFar) {
mockStage->queueResult(BSON("a" << i));
}
- ClusterClientCursorImpl cursor(_opCtx.get(),
- std::move(mockStage),
- ClusterClientCursorParams(NamespaceString("unused"), {}),
- boost::none);
+ ClusterClientCursorImpl cursor(
+ _opCtx.get(),
+ std::move(mockStage),
+ ClusterClientCursorParams(NamespaceString("unused"), APIParameters(), {}),
+ boost::none);
ASSERT_EQ(cursor.getNumReturnedSoFar(), 0);
@@ -251,6 +252,24 @@ TEST_F(ClusterClientCursorImplTest, ShouldStoreLSIDIfSetOnOpCtx) {
}
}
+TEST_F(ClusterClientCursorImplTest, ShouldStoreAPIParameters) {
+ auto mockStage = std::make_unique<RouterStageMock>(_opCtx.get());
+
+ APIParameters apiParams = APIParameters();
+ apiParams.setAPIVersion("2");
+ apiParams.setAPIStrict(true);
+ apiParams.setAPIDeprecationErrors(true);
+
+ ClusterClientCursorParams params(NamespaceString("test"), apiParams, {});
+ ClusterClientCursorImpl cursor(
+ _opCtx.get(), std::move(mockStage), std::move(params), boost::none);
+ auto storedAPIParams = cursor.getAPIParameters();
+
+ ASSERT_EQ(apiParams.getAPIVersion(), storedAPIParams.getAPIVersion());
+ ASSERT_EQ(apiParams.getAPIStrict(), storedAPIParams.getAPIStrict());
+ ASSERT_EQ(apiParams.getAPIDeprecationErrors(), storedAPIParams.getAPIDeprecationErrors());
+}
+
} // namespace
} // namespace mongo
diff --git a/src/mongo/s/query/cluster_client_cursor_mock.cpp b/src/mongo/s/query/cluster_client_cursor_mock.cpp
index e6f86dccade..9391f57f4fc 100644
--- a/src/mongo/s/query/cluster_client_cursor_mock.cpp
+++ b/src/mongo/s/query/cluster_client_cursor_mock.cpp
@@ -149,6 +149,14 @@ boost::optional<TxnNumber> ClusterClientCursorMock::getTxnNumber() const {
return _txnNumber;
}
+void ClusterClientCursorMock::setAPIParameters(APIParameters& apiParameters) {
+ _apiParameters = apiParameters;
+}
+
+APIParameters ClusterClientCursorMock::getAPIParameters() const {
+ return _apiParameters;
+}
+
boost::optional<ReadPreferenceSetting> ClusterClientCursorMock::getReadPreference() const {
return boost::none;
}
diff --git a/src/mongo/s/query/cluster_client_cursor_mock.h b/src/mongo/s/query/cluster_client_cursor_mock.h
index f72551a24da..a34ce2376eb 100644
--- a/src/mongo/s/query/cluster_client_cursor_mock.h
+++ b/src/mongo/s/query/cluster_client_cursor_mock.h
@@ -90,6 +90,10 @@ public:
boost::optional<TxnNumber> getTxnNumber() const final;
+ void setAPIParameters(APIParameters& apiParameters);
+
+ APIParameters getAPIParameters() const final;
+
boost::optional<ReadPreferenceSetting> getReadPreference() const final;
boost::optional<ReadConcernArgs> getReadConcern() const final;
@@ -141,6 +145,8 @@ private:
Date_t _lastUseDate;
std::uint64_t _nBatchesReturned = 0;
+
+ APIParameters _apiParameters = APIParameters();
};
} // namespace mongo
diff --git a/src/mongo/s/query/cluster_client_cursor_params.h b/src/mongo/s/query/cluster_client_cursor_params.h
index cd6563f842c..d8bb0ae8da0 100644
--- a/src/mongo/s/query/cluster_client_cursor_params.h
+++ b/src/mongo/s/query/cluster_client_cursor_params.h
@@ -39,6 +39,7 @@
#include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/user_name.h"
#include "mongo/db/cursor_id.h"
+#include "mongo/db/initialize_api_parameters.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/pipeline/pipeline.h"
#include "mongo/db/query/cursor_response.h"
@@ -68,9 +69,10 @@ using repl::ReadConcernArgs;
*/
struct ClusterClientCursorParams {
ClusterClientCursorParams(NamespaceString nss,
+ APIParameters apiParameters,
boost::optional<ReadPreferenceSetting> readPref = boost::none,
boost::optional<ReadConcernArgs> readConcernArgs = boost::none)
- : nsString(std::move(nss)) {
+ : nsString(std::move(nss)), apiParameters(std::move(apiParameters)) {
if (readPref) {
readPreference = std::move(readPref.get());
}
@@ -147,6 +149,9 @@ struct ClusterClientCursorParams {
// set.
TailableModeEnum tailableMode = TailableModeEnum::kNormal;
+ // The API parameters associated with the cursor.
+ APIParameters apiParameters;
+
// Set if a readPreference must be respected throughout the lifetime of the cursor.
boost::optional<ReadPreferenceSetting> readPreference;
diff --git a/src/mongo/s/query/cluster_cursor_manager_test.cpp b/src/mongo/s/query/cluster_cursor_manager_test.cpp
index aa8974161cc..1c68a2b3d2a 100644
--- a/src/mongo/s/query/cluster_cursor_manager_test.cpp
+++ b/src/mongo/s/query/cluster_cursor_manager_test.cpp
@@ -964,6 +964,32 @@ TEST_F(ClusterCursorManagerTest, DoNotDestroyKilledPinnedCursors) {
ASSERT(isMockCursorKilled(0));
}
+// Test that a cursor correctly stores API parameters.
+TEST_F(ClusterCursorManagerTest, CursorStoresAPIParameters) {
+ APIParameters apiParams = APIParameters();
+ apiParams.setAPIVersion("2");
+ apiParams.setAPIStrict(true);
+ apiParams.setAPIDeprecationErrors(true);
+
+ auto cursor = allocateMockCursor();
+ cursor->setAPIParameters(apiParams);
+
+ auto cursorId =
+ assertGet(getManager()->registerCursor(_opCtx.get(),
+ std::move(cursor),
+ nss,
+ ClusterCursorManager::CursorType::SingleTarget,
+ ClusterCursorManager::CursorLifetime::Mortal,
+ UserNameIterator()));
+ auto pinnedCursor =
+ assertGet(getManager()->checkOutCursor(nss, cursorId, _opCtx.get(), successAuthChecker));
+ auto storedAPIParams = pinnedCursor->getAPIParameters();
+
+ ASSERT_EQ(apiParams.getAPIVersion(), storedAPIParams.getAPIVersion());
+ ASSERT_EQ(apiParams.getAPIStrict(), storedAPIParams.getAPIStrict());
+ ASSERT_EQ(apiParams.getAPIDeprecationErrors(), storedAPIParams.getAPIDeprecationErrors());
+}
+
TEST_F(ClusterCursorManagerTest, CannotRegisterCursorDuringShutdown) {
ASSERT_OK(getManager()->registerCursor(_opCtx.get(),
allocateMockCursor(),
diff --git a/src/mongo/s/query/cluster_find.cpp b/src/mongo/s/query/cluster_find.cpp
index 6f374202b8f..8ceba8426ed 100644
--- a/src/mongo/s/query/cluster_find.cpp
+++ b/src/mongo/s/query/cluster_find.cpp
@@ -248,7 +248,8 @@ CursorId runQueryWithoutRetrying(OperationContext* opCtx,
// Construct the query and parameters. Defer setting skip and limit here until
// we determine if the query is targeting multi-shards or a single shard below.
- ClusterClientCursorParams params(query.nss(), readPref, ReadConcernArgs::get(opCtx));
+ ClusterClientCursorParams params(
+ query.nss(), APIParameters::get(opCtx), readPref, ReadConcernArgs::get(opCtx));
params.originatingCommandObj = CurOp::get(opCtx)->opDescription().getOwned();
params.batchSize = query.getQueryRequest().getEffectiveBatchSize();
params.tailableMode = query.getQueryRequest().getTailableMode();
@@ -440,6 +441,8 @@ Status setUpOperationContextStateForGetMore(OperationContext* opCtx,
ReadConcernArgs::get(opCtx) = *readConcern;
}
+ APIParameters::get(opCtx) = cursor->getAPIParameters();
+
// If the originating command had a 'comment' field, we extract it and set it on opCtx. Note
// that if the 'getMore' command itself has a 'comment' field, we give precedence to it.
auto comment = cursor->getOriginatingCommand()["comment"];
diff --git a/src/mongo/s/query/store_possible_cursor.cpp b/src/mongo/s/query/store_possible_cursor.cpp
index b76a47cddbe..6b6391dbb27 100644
--- a/src/mongo/s/query/store_possible_cursor.cpp
+++ b/src/mongo/s/query/store_possible_cursor.cpp
@@ -99,8 +99,10 @@ StatusWith<BSONObj> storePossibleCursor(OperationContext* opCtx,
return cmdResult;
}
- ClusterClientCursorParams params(
- incomingCursorResponse.getValue().getNSS(), boost::none, ReadConcernArgs::get(opCtx));
+ ClusterClientCursorParams params(incomingCursorResponse.getValue().getNSS(),
+ APIParameters::get(opCtx),
+ boost::none,
+ ReadConcernArgs::get(opCtx));
params.remotes.emplace_back();
auto& remoteCursor = params.remotes.back();
remoteCursor.setShardId(shardId.toString());