summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-01-20 16:10:10 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-01-21 11:57:37 -0500
commitcdbcef1a5f509a0677b0bdc6a74be1c82d39b9e2 (patch)
tree63eba7663d57079a24dde87124213bedf2f79eb0
parent35d64612e0e5398611e967c6003c29dee67c1ff6 (diff)
downloadmongo-cdbcef1a5f509a0677b0bdc6a74be1c82d39b9e2.tar.gz
SERVER-22247 Do not fail when parsing pre-2.2 sharding collection metadata
-rw-r--r--src/mongo/s/catalog/type_chunk.cpp1
-rw-r--r--src/mongo/s/catalog/type_chunk.h1
-rw-r--r--src/mongo/s/catalog/type_chunk_test.cpp20
-rw-r--r--src/mongo/s/catalog/type_collection.cpp19
-rw-r--r--src/mongo/s/catalog/type_collection.h3
-rw-r--r--src/mongo/s/catalog/type_collection_test.cpp40
6 files changed, 71 insertions, 13 deletions
diff --git a/src/mongo/s/catalog/type_chunk.cpp b/src/mongo/s/catalog/type_chunk.cpp
index f59bf0ea7a0..aea8197acb5 100644
--- a/src/mongo/s/catalog/type_chunk.cpp
+++ b/src/mongo/s/catalog/type_chunk.cpp
@@ -52,7 +52,6 @@ const BSONField<bool> ChunkType::jumbo("jumbo");
const BSONField<Date_t> ChunkType::DEPRECATED_lastmod("lastmod");
const BSONField<OID> ChunkType::DEPRECATED_epoch("lastmodEpoch");
-
StatusWith<ChunkType> ChunkType::fromBSON(const BSONObj& source) {
ChunkType chunk;
diff --git a/src/mongo/s/catalog/type_chunk.h b/src/mongo/s/catalog/type_chunk.h
index 739d652ce98..7690d141917 100644
--- a/src/mongo/s/catalog/type_chunk.h
+++ b/src/mongo/s/catalog/type_chunk.h
@@ -61,7 +61,6 @@ public:
static const BSONField<Date_t> DEPRECATED_lastmod;
static const BSONField<OID> DEPRECATED_epoch;
-
/**
* Constructs a new ChunkType object from BSON.
* Also does validation of the contents.
diff --git a/src/mongo/s/catalog/type_chunk_test.cpp b/src/mongo/s/catalog/type_chunk_test.cpp
index 8806bafefac..a971de3bf22 100644
--- a/src/mongo/s/catalog/type_chunk_test.cpp
+++ b/src/mongo/s/catalog/type_chunk_test.cpp
@@ -40,6 +40,7 @@ namespace {
using namespace mongo;
using std::string;
+using unittest::assertGet;
TEST(ChunkType, MissingRequiredFields) {
ChunkVersion chunkVersion(1, 2, OID::gen());
@@ -133,6 +134,25 @@ TEST(ChunkType, CorrectContents) {
ASSERT_OK(chunk.validate());
}
+TEST(ChunkType, Pre22Format) {
+ ChunkType chunk = assertGet(
+ ChunkType::fromBSON(BSON("_id"
+ << "test.mycol-a_MinKey"
+ << "lastmod" << Date_t::fromMillisSinceEpoch(1) << "ns"
+ << "test.mycol"
+ << "min" << BSON("a" << 10) << "max" << BSON("a" << 20) << "shard"
+ << "shard0001")));
+
+ ASSERT_OK(chunk.validate());
+ ASSERT_EQUALS(chunk.getName(), "test.mycol-a_MinKey");
+ ASSERT_EQUALS(chunk.getNS(), "test.mycol");
+ ASSERT_EQUALS(chunk.getMin(), BSON("a" << 10));
+ ASSERT_EQUALS(chunk.getMax(), BSON("a" << 20));
+ ASSERT_EQUALS(chunk.getVersion().toLong(), 1);
+ ASSERT(!chunk.getVersion().epoch().isSet());
+ ASSERT_EQUALS(chunk.getShard(), "shard0001");
+}
+
TEST(ChunkType, BadType) {
BSONObj obj = BSON(ChunkType::name() << 0);
StatusWith<ChunkType> chunkRes = ChunkType::fromBSON(obj);
diff --git a/src/mongo/s/catalog/type_collection.cpp b/src/mongo/s/catalog/type_collection.cpp
index 1d466314edb..87454e182a0 100644
--- a/src/mongo/s/catalog/type_collection.cpp
+++ b/src/mongo/s/catalog/type_collection.cpp
@@ -37,6 +37,12 @@
#include "mongo/util/assert_util.h"
namespace mongo {
+namespace {
+
+const BSONField<bool> kNoBalance("noBalance");
+const BSONField<bool> kDropped("dropped");
+
+} // namespace
const std::string CollectionType::ConfigNS = "config.collections";
@@ -45,9 +51,6 @@ const BSONField<OID> CollectionType::epoch("lastmodEpoch");
const BSONField<Date_t> CollectionType::updatedAt("lastmod");
const BSONField<BSONObj> CollectionType::keyPattern("key");
const BSONField<bool> CollectionType::unique("unique");
-const BSONField<bool> CollectionType::noBalance("noBalance");
-const BSONField<bool> CollectionType::dropped("dropped");
-
StatusWith<CollectionType> CollectionType::fromBSON(const BSONObj& source) {
CollectionType coll;
@@ -63,7 +66,7 @@ StatusWith<CollectionType> CollectionType::fromBSON(const BSONObj& source) {
{
OID collEpoch;
- Status status = bsonExtractOIDField(source, epoch.name(), &collEpoch);
+ Status status = bsonExtractOIDFieldWithDefault(source, epoch.name(), OID(), &collEpoch);
if (!status.isOK())
return status;
@@ -81,7 +84,7 @@ StatusWith<CollectionType> CollectionType::fromBSON(const BSONObj& source) {
{
bool collDropped;
- Status status = bsonExtractBooleanField(source, dropped.name(), &collDropped);
+ Status status = bsonExtractBooleanField(source, kDropped.name(), &collDropped);
if (status.isOK()) {
coll._dropped = collDropped;
} else if (status == ErrorCodes::NoSuchKey) {
@@ -122,7 +125,7 @@ StatusWith<CollectionType> CollectionType::fromBSON(const BSONObj& source) {
{
bool collNoBalance;
- Status status = bsonExtractBooleanField(source, noBalance.name(), &collNoBalance);
+ Status status = bsonExtractBooleanField(source, kNoBalance.name(), &collNoBalance);
if (status.isOK()) {
coll._allowBalance = !collNoBalance;
} else if (status == ErrorCodes::NoSuchKey) {
@@ -180,7 +183,7 @@ BSONObj CollectionType::toBSON() const {
}
builder.append(epoch.name(), _epoch.get_value_or(OID()));
builder.append(updatedAt.name(), _updatedAt.get_value_or(Date_t()));
- builder.append(dropped.name(), _dropped.get_value_or(false));
+ builder.append(kDropped.name(), _dropped.get_value_or(false));
// These fields are optional, so do not include them in the metadata for the purposes of
// consuming less space on the config servers.
@@ -194,7 +197,7 @@ BSONObj CollectionType::toBSON() const {
}
if (_allowBalance.is_initialized()) {
- builder.append(noBalance.name(), !_allowBalance.get());
+ builder.append(kNoBalance.name(), !_allowBalance.get());
}
return builder.obj();
diff --git a/src/mongo/s/catalog/type_collection.h b/src/mongo/s/catalog/type_collection.h
index 545c949e81e..062b65a7717 100644
--- a/src/mongo/s/catalog/type_collection.h
+++ b/src/mongo/s/catalog/type_collection.h
@@ -57,9 +57,6 @@ public:
static const BSONField<Date_t> updatedAt;
static const BSONField<BSONObj> keyPattern;
static const BSONField<bool> unique;
- static const BSONField<bool> noBalance;
- static const BSONField<bool> dropped;
-
/**
* Constructs a new DatabaseType object from BSON. Also does validation of the contents.
diff --git a/src/mongo/s/catalog/type_collection_test.cpp b/src/mongo/s/catalog/type_collection_test.cpp
index 9d3d3553ef7..893f3e6cb56 100644
--- a/src/mongo/s/catalog/type_collection_test.cpp
+++ b/src/mongo/s/catalog/type_collection_test.cpp
@@ -38,6 +38,7 @@ namespace {
using namespace mongo;
+using unittest::assertGet;
TEST(CollectionType, Empty) {
StatusWith<CollectionType> status = CollectionType::fromBSON(BSONObj());
@@ -63,6 +64,45 @@ TEST(CollectionType, Basic) {
ASSERT_EQUALS(coll.getDropped(), false);
}
+TEST(CollectionType, EpochCorrectness) {
+ CollectionType coll;
+ coll.setNs(NamespaceString{"db.coll"});
+ coll.setUpdatedAt(Date_t::fromMillisSinceEpoch(1));
+ coll.setKeyPattern(KeyPattern{BSON("a" << 1)});
+ coll.setUnique(false);
+ coll.setDropped(false);
+
+ // Validation will fail because we don't have epoch set. This ensures that if we read a
+ // collection with no epoch, we will write back one with epoch.
+ ASSERT_NOT_OK(coll.validate());
+
+ // We should be allowed to set empty epoch for dropped collections
+ coll.setDropped(true);
+ coll.setEpoch(OID());
+ ASSERT_OK(coll.validate());
+
+ // We should be allowed to set normal epoch for non-dropped collections
+ coll.setDropped(false);
+ coll.setEpoch(OID::gen());
+ ASSERT_OK(coll.validate());
+}
+
+TEST(CollectionType, Pre22Format) {
+ CollectionType coll = assertGet(
+ CollectionType::fromBSON(BSON("_id"
+ << "db.coll"
+ << "lastmod" << Date_t::fromMillisSinceEpoch(1) << "dropped"
+ << false << "key" << BSON("a" << 1) << "unique" << false)));
+
+ ASSERT(coll.getNs() == NamespaceString{"db.coll"});
+ ASSERT(!coll.getEpoch().isSet());
+ ASSERT_EQUALS(coll.getUpdatedAt(), Date_t::fromMillisSinceEpoch(1));
+ ASSERT_EQUALS(coll.getKeyPattern().toBSON(), BSON("a" << 1));
+ ASSERT_EQUALS(coll.getUnique(), false);
+ ASSERT_EQUALS(coll.getAllowBalance(), true);
+ ASSERT_EQUALS(coll.getDropped(), false);
+}
+
TEST(CollectionType, InvalidCollectionNamespace) {
const OID oid = OID::gen();
StatusWith<CollectionType> result = CollectionType::fromBSON(BSON(