diff options
author | XueruiFa <xuerui.fa@mongodb.com> | 2020-07-16 18:03:11 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-07-29 15:23:07 +0000 |
commit | 7b910aba3c500839692d142b4c64560b1fc2f29b (patch) | |
tree | f56189478f203aac17cbe9d10bf91b1969653155 /src/mongo/s | |
parent | 4b880132b11c16a4a0cba4e5c3ce77892dd01f7c (diff) | |
download | mongo-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/SConscript | 3 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_aggregation_planner.cpp | 6 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor.h | 6 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_impl.cpp | 4 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_impl.h | 2 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_impl_test.cpp | 27 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_mock.cpp | 8 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_mock.h | 6 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_client_cursor_params.h | 7 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_cursor_manager_test.cpp | 26 | ||||
-rw-r--r-- | src/mongo/s/query/cluster_find.cpp | 5 | ||||
-rw-r--r-- | src/mongo/s/query/store_possible_cursor.cpp | 6 |
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()); |