summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjannaerin <golden.janna@gmail.com>2022-04-07 16:53:58 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-25 16:33:52 +0000
commit5ef801809526ad8a8d5732d2689391e241ddf09e (patch)
treefec685dd70d1d620621e1072349c2637e628c6cc
parent33e3835fe308932345eec777f5201f7df762b428 (diff)
downloadmongo-5ef801809526ad8a8d5732d2689391e241ddf09e.tar.gz
SERVER-64608 Add tenantId to NamespaceString
-rw-r--r--src/mongo/db/SConscript4
-rw-r--r--src/mongo/db/commands/current_op_common.cpp5
-rw-r--r--src/mongo/db/db_raii.cpp1
-rw-r--r--src/mongo/db/namespace_string.cpp24
-rw-r--r--src/mongo/db/namespace_string.h95
-rw-r--r--src/mongo/db/namespace_string_test.cpp84
-rw-r--r--src/mongo/db/pipeline/aggregation_request_helper.cpp3
-rw-r--r--src/mongo/db/pipeline/aggregation_request_test.cpp3
-rw-r--r--src/mongo/db/pipeline/change_stream_event_transform_test.cpp7
-rw-r--r--src/mongo/db/pipeline/document_source_change_stream_add_post_image_test.cpp6
-rw-r--r--src/mongo/db/pipeline/document_source_change_stream_test.cpp6
-rw-r--r--src/mongo/db/pipeline/document_source_current_op_test.cpp6
-rw-r--r--src/mongo/db/pipeline/document_source_facet_test.cpp3
-rw-r--r--src/mongo/db/pipeline/pipeline_test.cpp9
-rw-r--r--src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp2
-rw-r--r--src/mongo/db/repl/tenant_oplog_applier_test.cpp107
-rw-r--r--src/mongo/db/tenant_database_name.cpp21
-rw-r--r--src/mongo/db/tenant_database_name.h17
-rw-r--r--src/mongo/db/tenant_database_name_test.cpp6
-rw-r--r--src/mongo/s/commands/cluster_list_collections_cmd.cpp3
20 files changed, 289 insertions, 123 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index e028a244889..61d3585d772 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -84,7 +84,6 @@ env.Library(
target='multitenancy',
source=[
'multitenancy.cpp',
- 'tenant_database_name.cpp',
],
LIBDEPS=[
'multitenancy_params',
@@ -94,7 +93,6 @@ env.Library(
'$BUILD_DIR/mongo/db/auth/auth',
'$BUILD_DIR/mongo/db/auth/security_token',
'$BUILD_DIR/mongo/idl/feature_flag',
- 'namespace_string',
'server_feature_flags',
]
)
@@ -247,10 +245,12 @@ env.Library(
target='namespace_string',
source=[
'namespace_string.cpp',
+ 'tenant_database_name.cpp',
],
LIBDEPS=[
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/repl/optime',
+ 'multitenancy_params',
],
LIBDEPS_PRIVATE=[
'server_options_core',
diff --git a/src/mongo/db/commands/current_op_common.cpp b/src/mongo/db/commands/current_op_common.cpp
index 6b816a79057..7e82a137c92 100644
--- a/src/mongo/db/commands/current_op_common.cpp
+++ b/src/mongo/db/commands/current_op_common.cpp
@@ -110,8 +110,9 @@ bool CurrentOpCommandBase::run(OperationContext* opCtx,
pipeline.push_back(groupBuilder.obj());
// Pipeline is complete; create an AggregateCommandRequest for $currentOp.
- AggregateCommandRequest request(NamespaceString::makeCollectionlessAggregateNSS("admin"),
- std::move(pipeline));
+ AggregateCommandRequest request(
+ NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "admin")),
+ std::move(pipeline));
// Run the pipeline and obtain a CursorResponse.
auto aggResults = uassertStatusOK(runAggregation(opCtx, request));
diff --git a/src/mongo/db/db_raii.cpp b/src/mongo/db/db_raii.cpp
index b0d94e170ec..3a0b72f6bc8 100644
--- a/src/mongo/db/db_raii.cpp
+++ b/src/mongo/db/db_raii.cpp
@@ -876,6 +876,7 @@ AutoGetCollectionForReadCommandLockFree::AutoGetCollectionForReadCommandLockFree
OldClientContext::OldClientContext(OperationContext* opCtx, const std::string& ns, bool doVersion)
: _opCtx(opCtx) {
+ // TODO SERVER-65488 Grab the TenantDatabaseName from the NamespaceString passed in
const auto dbName = nsToDatabaseSubstring(ns);
const TenantDatabaseName tenantDbName(boost::none, dbName);
_db = DatabaseHolder::get(opCtx)->getDb(opCtx, tenantDbName);
diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp
index d6bc8ced42f..f3099235fca 100644
--- a/src/mongo/db/namespace_string.cpp
+++ b/src/mongo/db/namespace_string.cpp
@@ -35,6 +35,7 @@
#include "mongo/base/parse_number.h"
#include "mongo/base/status.h"
+#include "mongo/db/multitenancy_gen.h"
#include "mongo/db/server_options.h"
#include "mongo/util/str.h"
@@ -165,6 +166,23 @@ const NamespaceString NamespaceString::kCompactStructuredEncryptionCoordinatorNa
const NamespaceString NamespaceString::kClusterParametersNamespace(NamespaceString::kConfigDb,
"clusterParameters");
+NamespaceString NamespaceString::parseFromStringExpectTenantIdInMultitenancyMode(StringData ns) {
+ if (!gMultitenancySupport) {
+ return NamespaceString(ns, boost::none);
+ }
+
+ auto tenantDelim = ns.find('_');
+ auto collDelim = ns.find('.');
+ // If the first '_' is after the '.' that separates the db and coll names, the '_' is part
+ // of the coll name and is not a db prefix.
+ if (tenantDelim == std::string::npos || collDelim < tenantDelim) {
+ return NamespaceString(ns, boost::none);
+ }
+
+ const TenantId tenantId(OID(ns.substr(0, tenantDelim)));
+ return NamespaceString(ns.substr(tenantDelim + 1, ns.size() - 1 - tenantDelim), tenantId);
+}
+
bool NamespaceString::isListCollectionsCursorNS() const {
return coll() == listCollectionsCursorCol;
}
@@ -242,15 +260,15 @@ bool NamespaceString::mustBeAppliedInOwnOplogBatch() const {
_ns == kTenantMigrationRecipientsNamespace.ns();
}
-NamespaceString NamespaceString::makeListCollectionsNSS(StringData dbName) {
+NamespaceString NamespaceString::makeListCollectionsNSS(const TenantDatabaseName& dbName) {
NamespaceString nss(dbName, listCollectionsCursorCol);
dassert(nss.isValid());
dassert(nss.isListCollectionsCursorNS());
return nss;
}
-NamespaceString NamespaceString::makeCollectionlessAggregateNSS(StringData dbname) {
- NamespaceString nss(dbname, collectionlessAggregateCursorCol);
+NamespaceString NamespaceString::makeCollectionlessAggregateNSS(const TenantDatabaseName& dbName) {
+ NamespaceString nss(dbName, collectionlessAggregateCursorCol);
dassert(nss.isValid());
dassert(nss.isCollectionlessAggregateNS());
return nss;
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index c4bbc52fcbd..5dfcac951e3 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -39,6 +39,8 @@
#include "mongo/bson/util/builder.h"
#include "mongo/db/repl/optime.h"
#include "mongo/db/server_options.h"
+#include "mongo/db/tenant_database_name.h"
+#include "mongo/db/tenant_id.h"
#include "mongo/logv2/log_attr.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/uuid.h"
@@ -222,37 +224,48 @@ public:
/**
* Constructs an empty NamespaceString.
*/
- NamespaceString() : _ns(), _dotIndex(std::string::npos) {}
+ NamespaceString() : _ns(), _dotIndex(std::string::npos), _dbName() {}
/**
- * Constructs a NamespaceString from the fully qualified namespace named in "ns".
+ * Constructs a NamespaceString from the fully qualified namespace named in "ns" and the
+ * tenantId. "ns" is NOT expected to contain the tenantId.
*/
- explicit NamespaceString(StringData ns) {
- _ns = ns.toString(); // copy to our buffer
+ explicit NamespaceString(boost::optional<TenantId> tenantId, StringData ns) {
+ _ns = tenantId ? tenantId->toString() + "_" + ns.toString()
+ : ns.toString(); // copy to our buffer
_dotIndex = _ns.find('.');
uassert(ErrorCodes::InvalidNamespace,
"namespaces cannot have embedded null characters",
_ns.find('\0') == std::string::npos);
+
+ auto db = _dotIndex == std::string::npos ? ns : ns.substr(0, _dotIndex);
+ _dbName = TenantDatabaseName(tenantId, db);
}
+ // TODO SERVER-65920 Remove this constructor once all constructor call sites have been updated
+ // to pass tenantId explicitly
+ explicit NamespaceString(StringData ns, boost::optional<TenantId> tenantId = boost::none)
+ : NamespaceString(tenantId, ns) {}
+
/**
* Constructs a NamespaceString for the given database and collection names.
* "dbName" must not contain a ".", and "collectionName" must not start with one.
*/
- NamespaceString(StringData dbName, StringData collectionName)
- : _ns(dbName.size() + collectionName.size() + 1, '\0') {
+ NamespaceString(TenantDatabaseName dbName, StringData collectionName)
+ : _ns(dbName.fullName().size() + collectionName.size() + 1, '\0') {
uassert(ErrorCodes::InvalidNamespace,
- "'.' is an invalid character in the database name: " + dbName,
- dbName.find('.') == std::string::npos);
+ "'.' is an invalid character in the database name: " + dbName.dbName(),
+ dbName.dbName().find('.') == std::string::npos);
uassert(ErrorCodes::InvalidNamespace,
"Collection names cannot start with '.': " + collectionName,
collectionName.empty() || collectionName[0] != '.');
- std::string::iterator it = std::copy(dbName.begin(), dbName.end(), _ns.begin());
+ auto db = dbName.fullName();
+ std::string::iterator it = std::copy(db.begin(), db.end(), _ns.begin());
*it = '.';
++it;
it = std::copy(collectionName.begin(), collectionName.end(), it);
- _dotIndex = dbName.size();
+ _dotIndex = db.size();
dassert(it == _ns.end());
dassert(_ns[_dotIndex] == '.');
@@ -260,19 +273,42 @@ public:
uassert(ErrorCodes::InvalidNamespace,
"namespaces cannot have embedded null characters",
_ns.find('\0') == std::string::npos);
+
+ _dbName = std::move(dbName);
}
/**
+ * Constructs a NamespaceString for the given db name, collection name, and tenantId.
+ * "db" must not contain a ".", and "collectionName" must not start with one. "dbName" is
+ * NOT expected to contain a tenantId.
+ */
+ NamespaceString(boost::optional<TenantId> tenantId, StringData db, StringData collectionName)
+ : NamespaceString(TenantDatabaseName(tenantId, db), collectionName) {}
+
+ // TODO SERVER-65920 Remove this constructor once all constructor call sites have been updated
+ // to pass tenantId explicitly
+ NamespaceString(StringData db,
+ StringData collectionName,
+ boost::optional<TenantId> tenantId = boost::none)
+ : NamespaceString(TenantDatabaseName(tenantId, db), collectionName) {}
+
+ /**
+ * Constructs a NamespaceString from the string 'ns'. Should only be used when reading a
+ * namespace from disk. 'ns' is expected to contain a tenantId when running in Serverless mode.
+ */
+ static NamespaceString parseFromStringExpectTenantIdInMultitenancyMode(StringData ns);
+
+ /**
* Constructs the namespace '<dbName>.$cmd.aggregate', which we use as the namespace for
* aggregation commands with the format {aggregate: 1}.
*/
- static NamespaceString makeCollectionlessAggregateNSS(StringData dbName);
+ static NamespaceString makeCollectionlessAggregateNSS(const TenantDatabaseName& dbName);
/**
* Constructs a NamespaceString representing a listCollections namespace. The format for this
* namespace is "<dbName>.$cmd.listCollections".
*/
- static NamespaceString makeListCollectionsNSS(StringData dbName);
+ static NamespaceString makeListCollectionsNSS(const TenantDatabaseName& dbName);
/**
* NOTE: DollarInDbNameBehavior::allow is deprecated.
@@ -285,8 +321,17 @@ public:
Allow, // Deprecated
};
+ boost::optional<TenantId> tenantId() const {
+ return _dbName.tenantId();
+ }
+
StringData db() const {
- return _dotIndex == std::string::npos ? _ns : StringData(_ns.data(), _dotIndex);
+ // TODO SERVER-65456 Remove this function.
+ return StringData(_dbName.fullName());
+ }
+
+ TenantDatabaseName dbName() const {
+ return _dbName;
}
StringData coll() const {
@@ -541,7 +586,7 @@ public:
* contain a $ should be checked explicitly.
* @return if db is an allowed database name
*/
- static bool validDBName(StringData db,
+ static bool validDBName(StringData dbString,
DollarInDbNameBehavior behavior = DollarInDbNameBehavior::Disallow);
/**
@@ -603,6 +648,7 @@ public:
private:
std::string _ns;
size_t _dotIndex = 0;
+ TenantDatabaseName _dbName;
};
/**
@@ -612,8 +658,15 @@ private:
class NamespaceStringOrUUID {
public:
NamespaceStringOrUUID(NamespaceString nss) : _nss(std::move(nss)) {}
- NamespaceStringOrUUID(std::string dbname, UUID uuid)
+ NamespaceStringOrUUID(TenantDatabaseName dbname, UUID uuid)
: _uuid(std::move(uuid)), _dbname(std::move(dbname)) {}
+ NamespaceStringOrUUID(boost::optional<TenantId> tenantId, std::string db, UUID uuid)
+ : _uuid(std::move(uuid)), _dbname(TenantDatabaseName(std::move(tenantId), std::move(db))) {}
+ // TODO SERVER-65920 Remove once all call sites have been changed to take tenantId explicitly
+ NamespaceStringOrUUID(std::string db,
+ UUID uuid,
+ boost::optional<TenantId> tenantId = boost::none)
+ : _uuid(std::move(uuid)), _dbname(TenantDatabaseName(std::move(tenantId), std::move(db))) {}
const boost::optional<NamespaceString>& nss() const {
return _nss;
@@ -630,7 +683,11 @@ public:
/**
* Returns database name if this object was initialized with a UUID.
*/
- const std::string& dbname() const {
+ std::string dbname() const {
+ return _dbname ? _dbname->dbName() : "";
+ }
+
+ const boost::optional<TenantDatabaseName>& dbnameWithTenant() const {
return _dbname;
}
@@ -642,7 +699,7 @@ public:
* Returns database name derived from either '_nss' or '_dbname'.
*/
StringData db() const {
- return _nss ? _nss->db() : StringData(_dbname);
+ return _nss ? _nss->db() : StringData(_dbname->dbName());
}
/**
@@ -663,10 +720,10 @@ private:
// When seralizing, if both '_nss' and '_uuid' are present, use '_nss'.
bool _preferNssForSerialization = false;
- // Empty string when '_nss' is non-none, and contains the database name when '_uuid' is
+ // Empty when '_nss' is non-none, and contains the database name when '_uuid' is
// non-none. Although the UUID specifies a collection uniquely, we must later verify that the
// collection belongs to the database named here.
- std::string _dbname;
+ boost::optional<TenantDatabaseName> _dbname;
};
std::ostream& operator<<(std::ostream& stream, const NamespaceString& nss);
diff --git a/src/mongo/db/namespace_string_test.cpp b/src/mongo/db/namespace_string_test.cpp
index 1a81e856e5f..6fc57751e1e 100644
--- a/src/mongo/db/namespace_string_test.cpp
+++ b/src/mongo/db/namespace_string_test.cpp
@@ -27,8 +27,11 @@
* it in the license file.
*/
+#include <boost/optional.hpp>
+
#include "mongo/platform/basic.h"
+#include "mongo/db/multitenancy_gen.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/repl/optime.h"
#include "mongo/unittest/unittest.h"
@@ -277,7 +280,8 @@ TEST(NamespaceStringTest, NamespaceStringParse5) {
}
TEST(NamespaceStringTest, makeListCollectionsNSIsCorrect) {
- NamespaceString ns = NamespaceString::makeListCollectionsNSS("DB");
+ NamespaceString ns =
+ NamespaceString::makeListCollectionsNSS(TenantDatabaseName(boost::none, "DB"));
ASSERT_EQUALS("DB", ns.db());
ASSERT_EQUALS("$cmd.listCollections", ns.coll());
ASSERT(ns.isValid());
@@ -296,5 +300,83 @@ TEST(NamespaceStringTest, EmptyNSStringReturnsEmptyDb) {
ASSERT_EQ(nss.db(), StringData{});
}
+TEST(NamespaceStringTest, NSSWithTenantId) {
+ TenantId tenantId(OID::gen());
+ std::string tenantNsStr = str::stream() << tenantId.toString() << "_foo.bar";
+
+ NamespaceString nss("foo.bar", tenantId);
+ ASSERT_EQ(nss.ns(), tenantNsStr);
+ ASSERT_EQ(nss.toString(), tenantNsStr);
+ ASSERT(nss.tenantId());
+ ASSERT_EQ(*nss.tenantId(), tenantId);
+
+ TenantDatabaseName dbName(tenantId, "foo");
+ NamespaceString nss2(dbName, "bar");
+ ASSERT_EQ(nss2.ns(), tenantNsStr);
+ ASSERT_EQ(nss2.toString(), tenantNsStr);
+ ASSERT(nss2.tenantId());
+ ASSERT_EQ(*nss2.tenantId(), tenantId);
+
+ NamespaceString nss3("foo", "bar", tenantId);
+ ASSERT_EQ(nss3.ns(), tenantNsStr);
+ ASSERT_EQ(nss3.toString(), tenantNsStr);
+ ASSERT(nss3.tenantId());
+ ASSERT_EQ(*nss3.tenantId(), tenantId);
+}
+
+TEST(NamespaceStringTest, NSSNoCollectionWithTenantId) {
+ TenantId tenantId(OID::gen());
+ std::string tenantNsStr = str::stream() << tenantId.toString() << "_foo";
+
+ NamespaceString nss("foo", tenantId);
+ ASSERT_EQ(nss.ns(), tenantNsStr);
+ ASSERT_EQ(nss.toString(), tenantNsStr);
+ ASSERT(nss.tenantId());
+ ASSERT_EQ(*nss.tenantId(), tenantId);
+
+ TenantDatabaseName dbName(tenantId, "foo");
+ NamespaceString nss2(dbName, "");
+ ASSERT(nss2.tenantId());
+ ASSERT_EQ(*nss2.tenantId(), tenantId);
+
+ NamespaceString nss3("foo", "", tenantId);
+ ASSERT(nss3.tenantId());
+ ASSERT_EQ(*nss3.tenantId(), tenantId);
+}
+
+TEST(NamespaceStringTest, ParseNSSWithTenantId) {
+ gMultitenancySupport = true;
+
+ TenantId tenantId(OID::gen());
+ std::string tenantNsStr = str::stream() << tenantId.toString() << "_foo.bar";
+
+ NamespaceString nss =
+ NamespaceString::parseFromStringExpectTenantIdInMultitenancyMode(tenantNsStr);
+ ASSERT_EQ(nss.ns(), tenantNsStr);
+ ASSERT(nss.tenantId());
+ ASSERT_EQ(*nss.tenantId(), tenantId);
+}
+
+TEST(NamespaceStringTest, CompareNSSWithTenantId) {
+ TenantId tenantIdMin(OID("000000000000000000000000"));
+ TenantId tenantIdMax(OID::max());
+
+ ASSERT(NamespaceString(tenantIdMin, "foo.bar") == NamespaceString(tenantIdMin, "foo.bar"));
+
+ ASSERT(NamespaceString(tenantIdMin, "foo.bar") != NamespaceString(tenantIdMax, "foo.bar"));
+ ASSERT(NamespaceString(tenantIdMin, "foo.bar") != NamespaceString(tenantIdMin, "zoo.bar"));
+
+ ASSERT(NamespaceString(tenantIdMin, "foo.bar") < NamespaceString(tenantIdMax, "foo.bar"));
+ ASSERT(NamespaceString(tenantIdMin, "foo.bar") < NamespaceString(tenantIdMin, "zoo.bar"));
+ ASSERT(NamespaceString(tenantIdMin, "zoo.bar") < NamespaceString(tenantIdMax, "foo.bar"));
+
+ ASSERT(NamespaceString(tenantIdMax, "foo.bar") > NamespaceString(tenantIdMin, "foo.bar"));
+ ASSERT(NamespaceString(tenantIdMin, "zoo.bar") > NamespaceString(tenantIdMin, "foo.bar"));
+ ASSERT(NamespaceString(tenantIdMax, "foo.bar") > NamespaceString(tenantIdMin, "zoo.bar"));
+
+ ASSERT(NamespaceString(tenantIdMin, "foo.bar") <= NamespaceString(tenantIdMin, "foo.bar"));
+ ASSERT(NamespaceString(tenantIdMin, "foo.bar") >= NamespaceString(tenantIdMin, "foo.bar"));
+}
+
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/pipeline/aggregation_request_helper.cpp b/src/mongo/db/pipeline/aggregation_request_helper.cpp
index 04fcc4023e3..e73a814e0c8 100644
--- a/src/mongo/db/pipeline/aggregation_request_helper.cpp
+++ b/src/mongo/db/pipeline/aggregation_request_helper.cpp
@@ -127,7 +127,8 @@ NamespaceString parseNs(const std::string& dbname, const BSONObj& cmdObj) {
<< firstElement.fieldNameStringData()
<< "' field must specify a collection name or 1",
firstElement.number() == 1);
- return NamespaceString::makeCollectionlessAggregateNSS(dbname);
+ return NamespaceString::makeCollectionlessAggregateNSS(
+ TenantDatabaseName(boost::none, dbname));
} else {
uassert(ErrorCodes::TypeMismatch,
str::stream() << "collection name has invalid type: "
diff --git a/src/mongo/db/pipeline/aggregation_request_test.cpp b/src/mongo/db/pipeline/aggregation_request_test.cpp
index 947764892b7..4038b32dfd8 100644
--- a/src/mongo/db/pipeline/aggregation_request_test.cpp
+++ b/src/mongo/db/pipeline/aggregation_request_test.cpp
@@ -253,7 +253,8 @@ TEST(AggregationRequestTest, ShouldSerializeBatchSizeIfSetAndExplainFalse) {
}
TEST(AggregationRequestTest, ShouldSerialiseAggregateFieldToOneIfCollectionIsAggregateOneNSS) {
- NamespaceString nss = NamespaceString::makeCollectionlessAggregateNSS("a");
+ NamespaceString nss =
+ NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "a"));
AggregateCommandRequest request(nss, {});
auto expectedSerialization =
diff --git a/src/mongo/db/pipeline/change_stream_event_transform_test.cpp b/src/mongo/db/pipeline/change_stream_event_transform_test.cpp
index 5554f3d4203..2f4271e097f 100644
--- a/src/mongo/db/pipeline/change_stream_event_transform_test.cpp
+++ b/src/mongo/db/pipeline/change_stream_event_transform_test.cpp
@@ -123,9 +123,10 @@ TEST(ChangeStreamEventTransformTest, TestCreateViewTransform) {
Document{{"db", viewNss.db()}, {"coll", viewNss.coll()}}},
{DocumentSourceChangeStream::kOperationDescriptionField, opDescription}};
- ASSERT_DOCUMENT_EQ(
- applyTransformation(oplogEntry, NamespaceString::makeCollectionlessAggregateNSS("viewDB")),
- expectedDoc);
+ ASSERT_DOCUMENT_EQ(applyTransformation(oplogEntry,
+ NamespaceString::makeCollectionlessAggregateNSS(
+ TenantDatabaseName(boost::none, "viewDB"))),
+ expectedDoc);
}
TEST(ChangeStreamEventTransformTest, TestCreateViewOnSingleCollection) {
diff --git a/src/mongo/db/pipeline/document_source_change_stream_add_post_image_test.cpp b/src/mongo/db/pipeline/document_source_change_stream_add_post_image_test.cpp
index 25ca17bbbfa..0d4f8778b14 100644
--- a/src/mongo/db/pipeline/document_source_change_stream_add_post_image_test.cpp
+++ b/src/mongo/db/pipeline/document_source_change_stream_add_post_image_test.cpp
@@ -239,7 +239,8 @@ TEST_F(DocumentSourceChangeStreamAddPostImageTest,
ShouldErrorIfDatabaseMismatchOnCollectionlessNss) {
auto expCtx = getExpCtx();
- expCtx->ns = NamespaceString::makeCollectionlessAggregateNSS("test");
+ expCtx->ns =
+ NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "test"));
// Set up the lookup change post image stage.
auto lookupChangeStage = DocumentSourceChangeStreamAddPostImage::create(expCtx, getSpec());
@@ -264,7 +265,8 @@ TEST_F(DocumentSourceChangeStreamAddPostImageTest,
TEST_F(DocumentSourceChangeStreamAddPostImageTest, ShouldPassIfDatabaseMatchesOnCollectionlessNss) {
auto expCtx = getExpCtx();
- expCtx->ns = NamespaceString::makeCollectionlessAggregateNSS("test");
+ expCtx->ns =
+ NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "test"));
// Set up the lookup change post image stage.
auto lookupChangeStage = DocumentSourceChangeStreamAddPostImage::create(expCtx, getSpec());
diff --git a/src/mongo/db/pipeline/document_source_change_stream_test.cpp b/src/mongo/db/pipeline/document_source_change_stream_test.cpp
index 0d7c31b293c..cc559e218a5 100644
--- a/src/mongo/db/pipeline/document_source_change_stream_test.cpp
+++ b/src/mongo/db/pipeline/document_source_change_stream_test.cpp
@@ -2811,7 +2811,8 @@ TEST_F(ChangeStreamStageTest, UsesResumeTokenAsSortKeyIfNeedsMergeIsFalse) {
class ChangeStreamStageDBTest : public ChangeStreamStageTest {
public:
ChangeStreamStageDBTest()
- : ChangeStreamStageTest(NamespaceString::makeCollectionlessAggregateNSS(nss.db())) {}
+ : ChangeStreamStageTest(NamespaceString::makeCollectionlessAggregateNSS(
+ TenantDatabaseName(boost::none, nss.db()))) {}
};
TEST_F(ChangeStreamStageDBTest, TransformInsert) {
@@ -4468,7 +4469,8 @@ TEST_F(MultiTokenFormatVersionTest, CanResumeFromV2HighWaterMark) {
ResumeTokenData resumeToken = ResumeToken::makeHighWaterMarkToken(resumeTs, 2).getData();
resumeToken.version = 2;
auto expCtx = getExpCtxRaw();
- expCtx->ns = NamespaceString::makeCollectionlessAggregateNSS("unittests");
+ expCtx->ns = NamespaceString::makeCollectionlessAggregateNSS(
+ TenantDatabaseName(boost::none, "unittests"));
// Create a change stream spec that resumes after 'resumeToken'.
const auto spec =
diff --git a/src/mongo/db/pipeline/document_source_current_op_test.cpp b/src/mongo/db/pipeline/document_source_current_op_test.cpp
index 260bfbf0829..34daaa921ba 100644
--- a/src/mongo/db/pipeline/document_source_current_op_test.cpp
+++ b/src/mongo/db/pipeline/document_source_current_op_test.cpp
@@ -53,7 +53,8 @@ const std::string kMockShardName = "testshard";
class DocumentSourceCurrentOpTest : public AggregationContextFixture {
public:
DocumentSourceCurrentOpTest()
- : AggregationContextFixture(NamespaceString::makeCollectionlessAggregateNSS("admin")) {}
+ : AggregationContextFixture(NamespaceString::makeCollectionlessAggregateNSS(
+ TenantDatabaseName(boost::none, "admin"))) {}
};
/**
@@ -98,7 +99,8 @@ TEST_F(DocumentSourceCurrentOpTest, ShouldFailToParseIfSpecIsNotObject) {
TEST_F(DocumentSourceCurrentOpTest, ShouldFailToParseIfNotRunOnAdmin) {
const auto specObj = fromjson("{$currentOp:{}}");
- getExpCtx()->ns = NamespaceString::makeCollectionlessAggregateNSS("foo");
+ getExpCtx()->ns =
+ NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "foo"));
ASSERT_THROWS_CODE(DocumentSourceCurrentOp::createFromBson(specObj.firstElement(), getExpCtx()),
AssertionException,
ErrorCodes::InvalidNamespace);
diff --git a/src/mongo/db/pipeline/document_source_facet_test.cpp b/src/mongo/db/pipeline/document_source_facet_test.cpp
index 44e3d9668e9..01bded3cc1e 100644
--- a/src/mongo/db/pipeline/document_source_facet_test.cpp
+++ b/src/mongo/db/pipeline/document_source_facet_test.cpp
@@ -116,7 +116,8 @@ TEST_F(DocumentSourceFacetTest, ShouldSucceedWhenNamespaceIsCollectionless) {
auto ctx = getExpCtx();
auto spec = fromjson("{$facet: {a: [{$match: {}}]}}");
- ctx->ns = NamespaceString::makeCollectionlessAggregateNSS("unittests");
+ ctx->ns = NamespaceString::makeCollectionlessAggregateNSS(
+ TenantDatabaseName(boost::none, "unittests"));
ASSERT_TRUE(DocumentSourceFacet::createFromBson(spec.firstElement(), ctx).get());
}
diff --git a/src/mongo/db/pipeline/pipeline_test.cpp b/src/mongo/db/pipeline/pipeline_test.cpp
index 99eef08c31c..1842b77713a 100644
--- a/src/mongo/db/pipeline/pipeline_test.cpp
+++ b/src/mongo/db/pipeline/pipeline_test.cpp
@@ -4206,7 +4206,7 @@ TEST_F(PipelineValidateTest, AggregateOneNSNotValidForEmptyPipeline) {
const std::vector<BSONObj> rawPipeline = {};
auto ctx = getExpCtx();
- ctx->ns = NamespaceString::makeCollectionlessAggregateNSS("a");
+ ctx->ns = NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "a"));
ASSERT_THROWS_CODE(
Pipeline::parse(rawPipeline, ctx), AssertionException, ErrorCodes::InvalidNamespace);
@@ -4216,7 +4216,7 @@ TEST_F(PipelineValidateTest, AggregateOneNSNotValidIfInitialStageRequiresCollect
const std::vector<BSONObj> rawPipeline = {fromjson("{$match: {}}")};
auto ctx = getExpCtx();
- ctx->ns = NamespaceString::makeCollectionlessAggregateNSS("a");
+ ctx->ns = NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "a"));
ASSERT_THROWS_CODE(
Pipeline::parse(rawPipeline, ctx), AssertionException, ErrorCodes::InvalidNamespace);
@@ -4226,7 +4226,7 @@ TEST_F(PipelineValidateTest, AggregateOneNSValidIfInitialStageIsCollectionless)
auto ctx = getExpCtx();
auto collectionlessSource = DocumentSourceCollectionlessMock::create(ctx);
- ctx->ns = NamespaceString::makeCollectionlessAggregateNSS("a");
+ ctx->ns = NamespaceString::makeCollectionlessAggregateNSS(TenantDatabaseName(boost::none, "a"));
Pipeline::create({collectionlessSource}, ctx);
}
@@ -4247,7 +4247,8 @@ TEST_F(PipelineValidateTest, AggregateOneNSValidForFacetPipelineRegardlessOfInit
const std::vector<BSONObj> rawPipeline = {fromjson("{$facet: {subPipe: [{$match: {}}]}}")};
auto ctx = getExpCtx();
- ctx->ns = NamespaceString::makeCollectionlessAggregateNSS("unittests");
+ ctx->ns = NamespaceString::makeCollectionlessAggregateNSS(
+ TenantDatabaseName(boost::none, "unittests"));
ASSERT_THROWS_CODE(
Pipeline::parse(rawPipeline, ctx), AssertionException, ErrorCodes::InvalidNamespace);
diff --git a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
index de2abb00078..567ac101a75 100644
--- a/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
+++ b/src/mongo/db/repl/oplog_applier_impl_test_fixture.cpp
@@ -462,9 +462,11 @@ void createCollection(OperationContext* opCtx,
writeConflictRetry(opCtx, "createCollection", nss.ns(), [&] {
Lock::DBLock dbLk(opCtx, nss.db(), MODE_IX);
Lock::CollectionLock collLk(opCtx, nss, MODE_X);
+
OldClientContext ctx(opCtx, nss.ns());
auto db = ctx.db();
ASSERT_TRUE(db);
+
mongo::WriteUnitOfWork wuow(opCtx);
auto coll = db->createCollection(opCtx, nss, options);
ASSERT_TRUE(coll);
diff --git a/src/mongo/db/repl/tenant_oplog_applier_test.cpp b/src/mongo/db/repl/tenant_oplog_applier_test.cpp
index 17860543896..460865c8ed4 100644
--- a/src/mongo/db/repl/tenant_oplog_applier_test.cpp
+++ b/src/mongo/db/repl/tenant_oplog_applier_test.cpp
@@ -50,6 +50,7 @@
#include "mongo/db/repl/tenant_oplog_batcher.h"
#include "mongo/db/service_context_d_test_fixture.h"
#include "mongo/db/service_context_test_fixture.h"
+#include "mongo/db/tenant_id.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
#include "mongo/logv2/log.h"
#include "mongo/unittest/log_test.h"
@@ -114,8 +115,6 @@ private:
std::vector<MutableOplogEntry> _entries;
};
-constexpr auto dbName = "tenant_test"_sd;
-
class TenantOplogApplierTest : public ServiceContextMongoDTest {
public:
void setUp() override {
@@ -185,7 +184,8 @@ protected:
OplogBufferMock _oplogBuffer;
executor::NetworkInterfaceMock* _net;
std::shared_ptr<executor::ThreadPoolTaskExecutor> _executor;
- std::string _tenantId = "tenant";
+ std::string _tenantId = OID::gen().toString();
+ TenantDatabaseName _dbName = TenantDatabaseName(TenantId(OID(_tenantId)), "test");
UUID _migrationUuid = UUID::gen();
ServiceContext::UniqueOperationContext _opCtx;
TenantOplogApplierTestOpObserver* _opObserver; // Owned by service context opObserverRegistry
@@ -199,8 +199,8 @@ private:
TEST_F(TenantOplogApplierTest, NoOpsForSingleBatch) {
std::vector<OplogEntry> srcOps;
- srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(dbName, "foo"), UUID::gen()));
- srcOps.push_back(makeInsertOplogEntry(2, NamespaceString(dbName, "bar"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(_dbName, "foo"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(2, NamespaceString(_dbName, "bar"), UUID::gen()));
pushOps(srcOps);
auto writerPool = makeTenantMigrationWriterPool();
@@ -225,7 +225,7 @@ TEST_F(TenantOplogApplierTest, NoOpsForLargeBatch) {
std::vector<OplogEntry> srcOps;
// This should be big enough to use several threads to do the writing
for (int i = 0; i < 64; i++) {
- srcOps.push_back(makeInsertOplogEntry(i + 1, NamespaceString(dbName, "foo"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(i + 1, NamespaceString(_dbName, "foo"), UUID::gen()));
}
pushOps(srcOps);
@@ -250,10 +250,10 @@ TEST_F(TenantOplogApplierTest, NoOpsForLargeBatch) {
TEST_F(TenantOplogApplierTest, NoOpsForMultipleBatches) {
std::vector<OplogEntry> srcOps;
- srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(dbName, "foo"), UUID::gen()));
- srcOps.push_back(makeInsertOplogEntry(2, NamespaceString(dbName, "bar"), UUID::gen()));
- srcOps.push_back(makeInsertOplogEntry(3, NamespaceString(dbName, "baz"), UUID::gen()));
- srcOps.push_back(makeInsertOplogEntry(4, NamespaceString(dbName, "bif"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(_dbName, "foo"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(2, NamespaceString(_dbName, "bar"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(3, NamespaceString(_dbName, "baz"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(4, NamespaceString(_dbName, "bif"), UUID::gen()));
auto writerPool = makeTenantMigrationWriterPool();
@@ -283,18 +283,18 @@ TEST_F(TenantOplogApplierTest, NoOpsForMultipleBatches) {
TEST_F(TenantOplogApplierTest, NoOpsForLargeTransaction) {
std::vector<OplogEntry> innerOps1;
- innerOps1.push_back(makeInsertOplogEntry(11, NamespaceString(dbName, "bar"), UUID::gen()));
- innerOps1.push_back(makeInsertOplogEntry(12, NamespaceString(dbName, "bar"), UUID::gen()));
+ innerOps1.push_back(makeInsertOplogEntry(11, NamespaceString(_dbName, "bar"), UUID::gen()));
+ innerOps1.push_back(makeInsertOplogEntry(12, NamespaceString(_dbName, "bar"), UUID::gen()));
std::vector<OplogEntry> innerOps2;
- innerOps2.push_back(makeInsertOplogEntry(21, NamespaceString(dbName, "bar"), UUID::gen()));
- innerOps2.push_back(makeInsertOplogEntry(22, NamespaceString(dbName, "bar"), UUID::gen()));
+ innerOps2.push_back(makeInsertOplogEntry(21, NamespaceString(_dbName, "bar"), UUID::gen()));
+ innerOps2.push_back(makeInsertOplogEntry(22, NamespaceString(_dbName, "bar"), UUID::gen()));
std::vector<OplogEntry> innerOps3;
- innerOps3.push_back(makeInsertOplogEntry(31, NamespaceString(dbName, "bar"), UUID::gen()));
- innerOps3.push_back(makeInsertOplogEntry(32, NamespaceString(dbName, "bar"), UUID::gen()));
+ innerOps3.push_back(makeInsertOplogEntry(31, NamespaceString(_dbName, "bar"), UUID::gen()));
+ innerOps3.push_back(makeInsertOplogEntry(32, NamespaceString(_dbName, "bar"), UUID::gen()));
// Makes entries with ts from range [2, 5).
std::vector<OplogEntry> srcOps = makeMultiEntryTransactionOplogEntries(
- 2, dbName, /* prepared */ false, {innerOps1, innerOps2, innerOps3});
+ 2, _dbName.dbName(), /* prepared */ false, {innerOps1, innerOps2, innerOps3});
pushOps(srcOps);
auto writerPool = makeTenantMigrationWriterPool();
@@ -320,7 +320,7 @@ TEST_F(TenantOplogApplierTest, NoOpsForLargeTransaction) {
TEST_F(TenantOplogApplierTest, CommitUnpreparedTransaction_DataPartiallyApplied) {
createCollectionWithUuid(_opCtx.get(), NamespaceString::kSessionTransactionsTableNamespace);
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto lsid = makeLogicalSessionId(_opCtx.get());
TxnNumber txnNum(0);
@@ -372,7 +372,7 @@ TEST_F(TenantOplogApplierTest, CommitUnpreparedTransaction_DataPartiallyApplied)
}
TEST_F(TenantOplogApplierTest, ApplyInsert_DatabaseMissing) {
- auto entry = makeInsertOplogEntry(1, NamespaceString(dbName, "bar"), UUID::gen());
+ auto entry = makeInsertOplogEntry(1, NamespaceString(_dbName, "bar"), UUID::gen());
bool onInsertsCalled = false;
_opObserver->onInsertsFn = [&](OperationContext* opCtx,
const NamespaceString&,
@@ -393,8 +393,8 @@ TEST_F(TenantOplogApplierTest, ApplyInsert_DatabaseMissing) {
}
TEST_F(TenantOplogApplierTest, ApplyInsert_CollectionMissing) {
- createDatabase(_opCtx.get(), dbName);
- auto entry = makeInsertOplogEntry(1, NamespaceString(dbName, "bar"), UUID::gen());
+ createDatabase(_opCtx.get(), _dbName.fullName());
+ auto entry = makeInsertOplogEntry(1, NamespaceString(_dbName, "bar"), UUID::gen());
bool onInsertsCalled = false;
_opObserver->onInsertsFn = [&](OperationContext* opCtx,
const NamespaceString&,
@@ -415,7 +415,7 @@ TEST_F(TenantOplogApplierTest, ApplyInsert_CollectionMissing) {
}
TEST_F(TenantOplogApplierTest, ApplyInsert_InsertExisting) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
ASSERT_OK(getStorageInterface()->insertDocument(_opCtx.get(),
nss,
@@ -433,7 +433,6 @@ TEST_F(TenantOplogApplierTest, ApplyInsert_InsertExisting) {
};
pushOps({entry});
auto writerPool = makeTenantMigrationWriterPool();
-
auto applier = std::make_shared<TenantOplogApplier>(
_migrationUuid, _tenantId, OpTime(), &_oplogBuffer, _executor, writerPool.get());
ASSERT_OK(applier->startup());
@@ -448,7 +447,7 @@ TEST_F(TenantOplogApplierTest, ApplyInsert_InsertExisting) {
}
TEST_F(TenantOplogApplierTest, ApplyInsert_UniqueKey_InsertExisting) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
// Create unique key index on the collection.
@@ -483,7 +482,7 @@ TEST_F(TenantOplogApplierTest, ApplyInsert_UniqueKey_InsertExisting) {
}
TEST_F(TenantOplogApplierTest, ApplyInsert_Success) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto entry = makeInsertOplogEntry(1, nss, uuid);
bool onInsertsCalled = false;
@@ -491,7 +490,7 @@ TEST_F(TenantOplogApplierTest, ApplyInsert_Success) {
[&](OperationContext* opCtx, const NamespaceString& nss, const std::vector<BSONObj>& docs) {
ASSERT_FALSE(onInsertsCalled);
onInsertsCalled = true;
- ASSERT_EQUALS(nss.db(), dbName);
+ ASSERT_EQUALS(nss.db(), _dbName.fullName());
ASSERT_EQUALS(nss.coll(), "bar");
ASSERT_EQUALS(1, docs.size());
ASSERT_BSONOBJ_EQ(docs[0], entry.getObject());
@@ -513,9 +512,9 @@ TEST_F(TenantOplogApplierTest, ApplyInsert_Success) {
TEST_F(TenantOplogApplierTest, ApplyInserts_Grouped) {
// TODO(SERVER-50256): remove nss_workaround, which is used to work around a bug where
// the first operation assigned to a worker cannot be grouped.
- NamespaceString nss_workaround(dbName, "a");
- NamespaceString nss1(dbName, "bar");
- NamespaceString nss2(dbName, "baz");
+ NamespaceString nss_workaround(_dbName, "a");
+ NamespaceString nss1(_dbName, "bar");
+ NamespaceString nss2(_dbName, "baz");
auto uuid1 = createCollectionWithUuid(_opCtx.get(), nss1);
auto uuid2 = createCollectionWithUuid(_opCtx.get(), nss2);
std::vector<OplogEntry> entries;
@@ -567,7 +566,7 @@ TEST_F(TenantOplogApplierTest, ApplyInserts_Grouped) {
}
TEST_F(TenantOplogApplierTest, ApplyUpdate_MissingDocument) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto entry = makeOplogEntry(
repl::OpTypeEnum::kUpdate, nss, uuid, BSON("$set" << BSON("a" << 1)), BSON("_id" << 0));
@@ -596,7 +595,7 @@ TEST_F(TenantOplogApplierTest, ApplyUpdate_MissingDocument) {
}
TEST_F(TenantOplogApplierTest, ApplyUpdate_Success) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
ASSERT_OK(getStorageInterface()->insertDocument(_opCtx.get(), nss, {BSON("_id" << 0)}, 0));
auto entry = makeOplogEntry(
@@ -622,7 +621,7 @@ TEST_F(TenantOplogApplierTest, ApplyUpdate_Success) {
}
TEST_F(TenantOplogApplierTest, ApplyDelete_DatabaseMissing) {
- auto entry = makeOplogEntry(OpTypeEnum::kDelete, NamespaceString(dbName, "bar"), UUID::gen());
+ auto entry = makeOplogEntry(OpTypeEnum::kDelete, NamespaceString(_dbName, "bar"), UUID::gen());
bool onDeleteCalled = false;
_opObserver->onDeleteFn = [&](OperationContext* opCtx,
const NamespaceString&,
@@ -645,8 +644,8 @@ TEST_F(TenantOplogApplierTest, ApplyDelete_DatabaseMissing) {
}
TEST_F(TenantOplogApplierTest, ApplyDelete_CollectionMissing) {
- createDatabase(_opCtx.get(), dbName);
- auto entry = makeOplogEntry(OpTypeEnum::kDelete, NamespaceString(dbName, "bar"), UUID::gen());
+ createDatabase(_opCtx.get(), _dbName.fullName());
+ auto entry = makeOplogEntry(OpTypeEnum::kDelete, NamespaceString(_dbName, "bar"), UUID::gen());
bool onDeleteCalled = false;
_opObserver->onDeleteFn = [&](OperationContext* opCtx,
const NamespaceString&,
@@ -669,7 +668,7 @@ TEST_F(TenantOplogApplierTest, ApplyDelete_CollectionMissing) {
}
TEST_F(TenantOplogApplierTest, ApplyDelete_DocumentMissing) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto entry = makeOplogEntry(OpTypeEnum::kDelete, nss, uuid, BSON("_id" << 0));
bool onDeleteCalled = false;
@@ -694,7 +693,7 @@ TEST_F(TenantOplogApplierTest, ApplyDelete_DocumentMissing) {
}
TEST_F(TenantOplogApplierTest, ApplyDelete_Success) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
ASSERT_OK(getStorageInterface()->insertDocument(_opCtx.get(), nss, {BSON("_id" << 0)}, 0));
auto entry = makeOplogEntry(OpTypeEnum::kDelete, nss, uuid, BSON("_id" << 0));
@@ -710,7 +709,7 @@ TEST_F(TenantOplogApplierTest, ApplyDelete_Success) {
ASSERT_TRUE(opCtx->lockState()->isCollectionLockedForMode(nss, MODE_IX));
ASSERT_TRUE(opCtx->writesAreReplicated());
ASSERT_FALSE(args.fromMigrate);
- ASSERT_EQUALS(nss.db(), dbName);
+ ASSERT_EQUALS(nss.db(), _dbName.fullName());
ASSERT_EQUALS(nss.coll(), "bar");
ASSERT_EQUALS(uuid, observer_uuid);
};
@@ -729,7 +728,7 @@ TEST_F(TenantOplogApplierTest, ApplyDelete_Success) {
}
TEST_F(TenantOplogApplierTest, ApplyCreateCollCommand_CollExisting) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto op = BSON("op"
<< "c"
@@ -758,8 +757,8 @@ TEST_F(TenantOplogApplierTest, ApplyCreateCollCommand_CollExisting) {
}
TEST_F(TenantOplogApplierTest, ApplyRenameCollCommand_CollExisting) {
- NamespaceString nss1(dbName, "foo");
- NamespaceString nss2(dbName, "bar");
+ NamespaceString nss1(_dbName, "foo");
+ NamespaceString nss2(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss2);
auto op =
BSON("op"
@@ -792,7 +791,7 @@ TEST_F(TenantOplogApplierTest, ApplyRenameCollCommand_CollExisting) {
}
TEST_F(TenantOplogApplierTest, ApplyCreateCollCommand_Success) {
- NamespaceString nss(dbName, "t");
+ NamespaceString nss(_dbName, "t");
auto op =
BSON("op"
<< "c"
@@ -826,7 +825,7 @@ TEST_F(TenantOplogApplierTest, ApplyCreateCollCommand_Success) {
}
TEST_F(TenantOplogApplierTest, ApplyCreateIndexesCommand_Success) {
- NamespaceString nss(dbName, "t");
+ NamespaceString nss(_dbName, "t");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto op =
BSON("op"
@@ -867,7 +866,7 @@ TEST_F(TenantOplogApplierTest, ApplyCreateIndexesCommand_Success) {
}
TEST_F(TenantOplogApplierTest, ApplyStartIndexBuildCommand_Failure) {
- NamespaceString nss(dbName, "t");
+ NamespaceString nss(_dbName, "t");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto op = BSON("op"
<< "c"
@@ -920,7 +919,7 @@ TEST_F(TenantOplogApplierTest, ApplyCreateCollCommand_WrongNSS) {
}
TEST_F(TenantOplogApplierTest, ApplyDropIndexesCommand_IndexNotFound) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto op = BSON("op"
<< "c"
@@ -952,7 +951,7 @@ TEST_F(TenantOplogApplierTest, ApplyDropIndexesCommand_IndexNotFound) {
}
TEST_F(TenantOplogApplierTest, ApplyCollModCommand_IndexNotFound) {
- NamespaceString nss(dbName, "bar");
+ NamespaceString nss(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto op = BSON("op"
<< "c"
@@ -989,8 +988,8 @@ TEST_F(TenantOplogApplierTest, ApplyCollModCommand_IndexNotFound) {
}
TEST_F(TenantOplogApplierTest, ApplyCollModCommand_CollectionMissing) {
- createDatabase(_opCtx.get(), dbName);
- NamespaceString nss(dbName, "bar");
+ createDatabase(_opCtx.get(), _dbName.fullName());
+ NamespaceString nss(_dbName, "bar");
UUID uuid(UUID::gen());
auto op = BSON("op"
<< "c"
@@ -1053,7 +1052,7 @@ TEST_F(TenantOplogApplierTest, ApplyCRUD_WrongUUID) {
// Should not be able to apply a CRUD operation to a namespace not belonging to us, even if
// we claim it does in the nss field.
NamespaceString nss("notmytenant", "bar");
- NamespaceString nss_to_apply(dbName, "bar");
+ NamespaceString nss_to_apply(_dbName, "bar");
auto uuid = createCollectionWithUuid(_opCtx.get(), nss);
auto entry = makeInsertOplogEntry(1, nss_to_apply, uuid);
bool onInsertsCalled = false;
@@ -1124,7 +1123,7 @@ TEST_F(TenantOplogApplierTest, ApplyResumeTokenNoop_Success) {
TEST_F(TenantOplogApplierTest, ApplyInsertThenResumeTokenNoopInDifferentBatch_Success) {
std::vector<OplogEntry> srcOps;
- srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(dbName, "foo"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(_dbName, "foo"), UUID::gen()));
srcOps.push_back(makeNoopOplogEntry(2, TenantMigrationRecipientService::kNoopMsg));
pushOps(srcOps);
auto writerPool = makeTenantMigrationWriterPool();
@@ -1155,7 +1154,7 @@ TEST_F(TenantOplogApplierTest, ApplyInsertThenResumeTokenNoopInDifferentBatch_Su
TEST_F(TenantOplogApplierTest, ApplyResumeTokenNoopThenInsertInSameBatch_Success) {
std::vector<OplogEntry> srcOps;
srcOps.push_back(makeNoopOplogEntry(1, TenantMigrationRecipientService::kNoopMsg));
- srcOps.push_back(makeInsertOplogEntry(2, NamespaceString(dbName, "foo"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(2, NamespaceString(_dbName, "foo"), UUID::gen()));
pushOps(srcOps);
auto writerPool = makeTenantMigrationWriterPool();
@@ -1180,7 +1179,7 @@ TEST_F(TenantOplogApplierTest, ApplyResumeTokenNoopThenInsertInSameBatch_Success
TEST_F(TenantOplogApplierTest, ApplyResumeTokenInsertThenNoopSameTimestamp_Success) {
std::vector<OplogEntry> srcOps;
- srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(dbName, "foo"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(_dbName, "foo"), UUID::gen()));
srcOps.push_back(makeNoopOplogEntry(1, TenantMigrationRecipientService::kNoopMsg));
pushOps(srcOps);
ASSERT_EQ(srcOps[0].getOpTime(), srcOps[1].getOpTime());
@@ -1207,7 +1206,7 @@ TEST_F(TenantOplogApplierTest, ApplyResumeTokenInsertThenNoopSameTimestamp_Succe
TEST_F(TenantOplogApplierTest, ApplyResumeTokenInsertThenNoop_Success) {
std::vector<OplogEntry> srcOps;
- srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(dbName, "foo"), UUID::gen()));
+ srcOps.push_back(makeInsertOplogEntry(1, NamespaceString(_dbName, "foo"), UUID::gen()));
srcOps.push_back(makeNoopOplogEntry(2, TenantMigrationRecipientService::kNoopMsg));
pushOps(srcOps);
auto writerPool = makeTenantMigrationWriterPool();
@@ -1233,8 +1232,8 @@ TEST_F(TenantOplogApplierTest, ApplyResumeTokenInsertThenNoop_Success) {
TEST_F(TenantOplogApplierTest, ApplyInsert_MultiKeyIndex) {
createCollectionWithUuid(_opCtx.get(), NamespaceString::kSessionTransactionsTableNamespace);
- NamespaceString indexedNss(dbName, "indexedColl");
- NamespaceString nonIndexedNss(dbName, "nonIndexedColl");
+ NamespaceString indexedNss(_dbName, "indexedColl");
+ NamespaceString nonIndexedNss(_dbName, "nonIndexedColl");
auto indexedCollUUID = createCollectionWithUuid(_opCtx.get(), indexedNss);
createCollection(_opCtx.get(), nonIndexedNss, CollectionOptions());
diff --git a/src/mongo/db/tenant_database_name.cpp b/src/mongo/db/tenant_database_name.cpp
index 457763d206b..f1c8fb0eb9e 100644
--- a/src/mongo/db/tenant_database_name.cpp
+++ b/src/mongo/db/tenant_database_name.cpp
@@ -29,29 +29,10 @@
#include "mongo/db/tenant_database_name.h"
-#include "mongo/db/multitenancy_gen.h"
-#include "mongo/db/server_feature_flags_gen.h"
-
namespace mongo {
-TenantDatabaseName::TenantDatabaseName(boost::optional<TenantId> tenantId, StringData dbName) {
- // TODO SERVER-62114 Check instead if gMultitenancySupport is enabled.
- if (gFeatureFlagRequireTenantID.isEnabledAndIgnoreFCV())
- invariant(tenantId);
-
- _tenantId = tenantId;
- _dbName = dbName.toString();
-
- _tenantDbName =
- _tenantId ? boost::make_optional(_tenantId->toString() + "_" + _dbName) : boost::none;
-}
-
TenantDatabaseName TenantDatabaseName::createSystemTenantDbName(StringData dbName) {
- // TODO SERVER-62114 Check instead if gMultitenancySupport is enabled.
- if (gFeatureFlagRequireTenantID.isEnabledAndIgnoreFCV()) {
- return TenantDatabaseName(TenantId::kSystemTenantId, dbName);
- }
-
+ // TODO SERVER-62491 Use kSystemTenantId
return TenantDatabaseName(boost::none, dbName);
}
diff --git a/src/mongo/db/tenant_database_name.h b/src/mongo/db/tenant_database_name.h
index bf013d7fd4a..4ae9e6a6cf1 100644
--- a/src/mongo/db/tenant_database_name.h
+++ b/src/mongo/db/tenant_database_name.h
@@ -55,10 +55,21 @@ public:
* Constructs a TenantDatabaseName from the given tenantId and database name.
* "dbName" is expected only consist of a db name. It is the caller's responsibility to ensure
* the dbName is a valid db name.
- *
- * If featureFlagRequireTenantID is set, tenantId is required.
*/
- TenantDatabaseName(boost::optional<TenantId> tenantId, StringData dbName);
+ TenantDatabaseName(boost::optional<TenantId> tenantId, StringData dbName) {
+ _tenantId = tenantId;
+ _dbName = dbName.toString();
+
+ _tenantDbName =
+ _tenantId ? boost::make_optional(_tenantId->toString() + "_" + _dbName) : boost::none;
+ }
+
+ /**
+ * Prefer to use the constructor above.
+ * TODO SERVER-65456 Remove this constructor.
+ */
+ TenantDatabaseName(StringData dbName, boost::optional<TenantId> tenantId = boost::none)
+ : TenantDatabaseName(tenantId, dbName) {}
static TenantDatabaseName createSystemTenantDbName(StringData dbName);
diff --git a/src/mongo/db/tenant_database_name_test.cpp b/src/mongo/db/tenant_database_name_test.cpp
index 75d9550afef..dcf967402e0 100644
--- a/src/mongo/db/tenant_database_name_test.cpp
+++ b/src/mongo/db/tenant_database_name_test.cpp
@@ -68,10 +68,11 @@ TEST(TenantDatabaseNameTest, MultitenancySupportEnabledTenantIDNotRequired) {
ASSERT_EQUALS(std::string(tenantId.toString() + "_a"), tdnWithTenant.fullName());
}
+/*
+// TODO SERVER-65457 Re-enable these tests
+
DEATH_TEST(TenantDatabaseNameTest, TenantIDRequiredNoTenantIdAssigned, "invariant") {
RAIIServerParameterControllerForTest multitenanyController("multitenancySupport", true);
- // TODO SERVER-62114 Remove enabling this feature flag.
- RAIIServerParameterControllerForTest featureFlagController("featureFlagRequireTenantID", true);
TenantDatabaseName tdnWithoutTenant(boost::none, "a");
}
@@ -88,6 +89,7 @@ TEST(TenantDatabaseNameTest, TenantIDRequiredBasic) {
ASSERT_EQUALS(std::string("a"), tdn.dbName());
ASSERT_EQUALS(std::string(tenantId.toString() + "_a"), tdn.fullName());
}
+*/
TEST(TenantDatabaseNameTest, VerifyEqualsOperator) {
TenantId tenantId(OID::gen());
diff --git a/src/mongo/s/commands/cluster_list_collections_cmd.cpp b/src/mongo/s/commands/cluster_list_collections_cmd.cpp
index a279d772a8c..cb2b2a98813 100644
--- a/src/mongo/s/commands/cluster_list_collections_cmd.cpp
+++ b/src/mongo/s/commands/cluster_list_collections_cmd.cpp
@@ -222,7 +222,8 @@ public:
BSONObjBuilder& output) final {
CommandHelpers::handleMarkKillOnClientDisconnect(opCtx);
- const auto nss(NamespaceString::makeListCollectionsNSS(dbName));
+ const auto nss(
+ NamespaceString::makeListCollectionsNSS(TenantDatabaseName(boost::none, dbName)));
BSONObj newCmd = cmdObj;