summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlberto Lerner <alerner@10gen.com>2012-11-19 21:57:50 -0500
committerAlberto Lerner <alerner@10gen.com>2012-11-19 21:58:02 -0500
commit38a48227486caecfe45e4754418e22f804cdbf84 (patch)
tree8a1e1eb82c6199471844bef59f58c557c26d4e50
parent428bb865bfd24848ffba0fb9b9514264e5b3816e (diff)
downloadmongo-38a48227486caecfe45e4754418e22f804cdbf84.tar.gz
SERVER-939 Introduced type for config.shards collection.
-rw-r--r--src/mongo/s/SConscript5
-rw-r--r--src/mongo/s/field_parser.cpp18
-rw-r--r--src/mongo/s/field_parser.h5
-rw-r--r--src/mongo/s/field_parser_test.cpp18
-rw-r--r--src/mongo/s/type_shard.cpp100
-rw-r--r--src/mongo/s/type_shard.h127
-rw-r--r--src/mongo/s/type_shard_test.cpp52
7 files changed, 323 insertions, 2 deletions
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index 7a273dfeb33..e7a1bbdb739 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -6,7 +6,8 @@ env.StaticLibrary('config', ['cluster_constants.cpp',
'field_parser.cpp',
'type_chunk.cpp',
'type_collection.cpp',
- 'type_database.cpp'],
+ 'type_database.cpp',
+ 'type_shard.cpp'],
LIBDEPS=['$BUILD_DIR/mongo/base/base',
'$BUILD_DIR/mongo/bson'])
@@ -17,3 +18,5 @@ env.CppUnitTest('type_chunk_test', 'type_chunk_test.cpp', LIBDEPS=['config'])
env.CppUnitTest('type_collection_test', 'type_collection_test.cpp', LIBDEPS=['config'])
env.CppUnitTest('type_database_test', 'type_database_test.cpp', LIBDEPS=['config'])
+
+env.CppUnitTest('type_shard_test', 'type_shard_test.cpp', LIBDEPS=['config'])
diff --git a/src/mongo/s/field_parser.cpp b/src/mongo/s/field_parser.cpp
index 9d5080b16c5..b9be26e1e72 100644
--- a/src/mongo/s/field_parser.cpp
+++ b/src/mongo/s/field_parser.cpp
@@ -126,4 +126,22 @@ namespace mongo {
return false;
}
+ bool FieldParser::extract(BSONObj doc,
+ const BSONField<long long>& field,
+ const long long& def,
+ long long* out) {
+ BSONElement elem = doc[field.name()];
+ if (elem.eoo()) {
+ *out = def;
+ return true;
+ }
+
+ if (elem.type() == NumberLong) {
+ *out = elem.numberLong();
+ return true;
+ }
+
+ return false;
+ }
+
} // namespace mongo
diff --git a/src/mongo/s/field_parser.h b/src/mongo/s/field_parser.h
index 218ea0f89bf..bddae660562 100644
--- a/src/mongo/s/field_parser.h
+++ b/src/mongo/s/field_parser.h
@@ -67,6 +67,11 @@ namespace mongo {
const BSONField<OID>& field,
const OID& def,
OID* out);
+
+ static bool extract(BSONObj doc,
+ const BSONField<long long>& field,
+ const long long& def,
+ long long* out);
};
} // namespace mongo
diff --git a/src/mongo/s/field_parser_test.cpp b/src/mongo/s/field_parser_test.cpp
index ffa43ad13c1..298d10e03a2 100644
--- a/src/mongo/s/field_parser_test.cpp
+++ b/src/mongo/s/field_parser_test.cpp
@@ -42,6 +42,7 @@ namespace {
Date_t valDate;
string valString;
OID valOID;
+ long long valLong;
static BSONField<bool> aBool;
static BSONField<BSONArray> anArray;
@@ -49,6 +50,7 @@ namespace {
static BSONField<Date_t> aDate;
static BSONField<string> aString;
static BSONField<OID> anOID;
+ static BSONField<long long> aLong;
void setUp() {
valBool = true;
@@ -57,13 +59,15 @@ namespace {
valDate = 1ULL;
valString = "a string";
valOID = OID::gen();
+ valLong = 1LL;
doc = BSON(aBool(valBool) <<
anArray(valArray) <<
anObj(valObj) <<
aDate(valDate) <<
aString(valString) <<
- anOID(valOID));
+ anOID(valOID) <<
+ aLong(valLong));
}
void tearDown() {
@@ -76,6 +80,7 @@ namespace {
BSONField<Date_t> ExtractionFixture::aDate("aDate");
BSONField<string> ExtractionFixture::aString("aString");
BSONField<OID> ExtractionFixture::anOID("anOID");
+ BSONField<long long> ExtractionFixture::aLong("aLong");
TEST_F(ExtractionFixture, GetBool) {
BSONField<bool> notThere("otherBool");
@@ -144,4 +149,15 @@ namespace {
ASSERT_FALSE(FieldParser::extract(doc, wrongType, defOID, &val));
}
+ TEST_F(ExtractionFixture, GetLong) {
+ BSONField<long long> notThere("otherLong");
+ BSONField<long long> wrongType(aString.name());
+ long long val;
+ ASSERT_TRUE(FieldParser::extract(doc, aLong, 0, &val));
+ ASSERT_EQUALS(val, valLong);
+ ASSERT_TRUE(FieldParser::extract(doc, notThere, 0, &val));
+ ASSERT_EQUALS(val, 0);
+ ASSERT_FALSE(FieldParser::extract(doc, wrongType, 0, &val));
+ }
+
} // unnamed namespace
diff --git a/src/mongo/s/type_shard.cpp b/src/mongo/s/type_shard.cpp
new file mode 100644
index 00000000000..4269e88d7cc
--- /dev/null
+++ b/src/mongo/s/type_shard.cpp
@@ -0,0 +1,100 @@
+/**
+ * Copyright (C) 2012 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mongo/s/type_shard.h"
+
+#include "mongo/s/field_parser.h"
+#include "mongo/util/mongoutils/str.h"
+
+namespace mongo {
+
+ using mongoutils::str::stream;
+
+ const std::string ShardType::ConfigNS = "config.shards";
+
+ BSONField<std::string> ShardType::name("_id");
+ BSONField<std::string> ShardType::host("host");
+ BSONField<bool> ShardType::draining("draining");
+ BSONField<long long> ShardType::maxSize("maxSize");
+
+ ShardType::ShardType() {
+ clear();
+ }
+
+ ShardType::~ShardType() {
+ }
+
+ bool ShardType::isValid(std::string* errMsg) const {
+ std::string dummy;
+ if (errMsg == NULL) {
+ errMsg = &dummy;
+ }
+
+ // All the mandatory fields must be present.
+ if (_name.empty()) {
+ *errMsg = stream() << "missing " << name.name() << " field";
+ return false;
+ }
+ if (_host.empty()) {
+ *errMsg = stream() << "missing " << host.name() << " field";
+ return false;
+ }
+
+ return true;
+ }
+
+ BSONObj ShardType::toBSON() const {
+ BSONObjBuilder builder;
+ if (!_name.empty()) builder.append(name(), _name);
+ if (!_host.empty()) builder.append(host(), _host);
+ if (_draining) builder.append(draining(), _draining);
+ if (_maxSize > 0) builder.append(maxSize(), _maxSize);
+ return builder.obj();
+ }
+
+ void ShardType::parseBSON(BSONObj source) {
+ clear();
+
+ bool ok = true;
+ ok &= FieldParser::extract(source, name, "", &_name);
+ ok &= FieldParser::extract(source, host, "", &_host);
+ ok &= FieldParser::extract(source, draining, false, &_draining);
+ ok &= FieldParser::extract(source, maxSize, 0LL, &_maxSize);
+ if (! ok) {
+ clear();
+ }
+ }
+
+ void ShardType::clear() {
+ _name.clear();
+ _host.clear();
+ _draining = false;
+ _maxSize = 0;
+ }
+
+ void ShardType::cloneTo(ShardType* other) {
+ other->clear();
+ other->_name = _name;
+ other->_host = _host;
+ other->_draining = _draining;
+ other->_maxSize = _maxSize;
+ }
+
+ std::string ShardType::toString() const {
+ return toBSON().toString();
+ }
+
+} // namespace mongo
diff --git a/src/mongo/s/type_shard.h b/src/mongo/s/type_shard.h
new file mode 100644
index 00000000000..686fad638e8
--- /dev/null
+++ b/src/mongo/s/type_shard.h
@@ -0,0 +1,127 @@
+/**
+ * Copyright (C) 2012 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <string>
+
+#include "mongo/base/disallow_copying.h"
+#include "mongo/base/string_data.h"
+#include "mongo/db/jsobj.h"
+
+namespace mongo {
+
+ /**
+ * This class represents the layout and contents of documents contained in the
+ * config.shards collection. All manipulation of documents coming from that
+ * collection should be done with this class.
+ *
+ * Usage Example:
+ *
+ * DBClientBase* conn;
+ * BSONObj query = QUERY(ShardType::name("shard0000"));
+ * shardDoc = conn->findOne(ShardType::ConfigNS, query);
+ *
+ * // Process the response.
+ * ShardType shard;
+ * shard.fromBSON(shardDoc);
+ * if (! shard.isValid()) {
+ * // Can't use 'shard'. Take action.
+ * }
+ * // use 'shard'
+ *
+ */
+ class ShardType {
+ MONGO_DISALLOW_COPYING(ShardType);
+ public:
+
+ //
+ // schema declarations
+ //
+
+ // Name of the shard collection in the config server.
+ static const std::string ConfigNS;
+
+ // Field names and types in the shard collection type.
+ static BSONField<std::string> name;
+ static BSONField<std::string> host;
+ static BSONField<bool> draining;
+ static BSONField<long long> maxSize;
+
+ //
+ // shard type methods
+ //
+
+ ShardType();
+ ~ShardType();
+
+ /**
+ * Returns true if all the mandatory fields are present and have valid
+ * representations. Otherwise returns false and fills in the optional 'errMsg' string.
+ */
+ bool isValid(std::string* errMsg) const;
+
+ /**
+ * Returns the BSON representation of the entry.
+ */
+ BSONObj toBSON() const;
+
+ /**
+ * Clears and populates the internal state using the 'source' BSON object if the
+ * latter contains valid values. Otherwise clear the internal state.
+ */
+ void parseBSON(BSONObj source);
+
+ /**
+ * Clears the internal state.
+ */
+ void clear();
+
+ /**
+ * Copies all the fields present in 'this' to 'other'.
+ */
+ void cloneTo(ShardType* other);
+
+ /**
+ * Returns a string representation of the current internal state.
+ */
+ std::string toString() const;
+
+ //
+ // individual field accessors
+ //
+
+ void setName(const StringData& name) { _name = std::string(name.data(), name.size()); }
+ const std::string& getName() const { return _name; }
+
+ void setHost(const StringData& host) { _host = std::string(host.data(), host.size()); }
+ const std::string& getHost() const { return _host; }
+
+ void setDraining(bool draining) { _draining = draining; }
+ bool getDraining() const { return _draining; }
+
+ void setMaxSize(uint64_t maxSize) { _maxSize = maxSize; }
+ uint64_t getMaxSize() const { return _maxSize; }
+
+ private:
+ // Convention: (M)andatory, (O)ptional, (S)pecial rule.
+ std::string _name; // (M) shard's id
+ std::string _host; // (M) connection string for the host(s)
+ bool _draining; // (O) is it draining chunks?
+ long long _maxSize; // (O) maximum allowed disk space in MB
+ };
+
+} // namespace mongo
diff --git a/src/mongo/s/type_shard_test.cpp b/src/mongo/s/type_shard_test.cpp
new file mode 100644
index 00000000000..a316158175a
--- /dev/null
+++ b/src/mongo/s/type_shard_test.cpp
@@ -0,0 +1,52 @@
+/**
+ * Copyright (C) 2012 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mongo/pch.h"
+
+#include "mongo/s/type_shard.h"
+#include "mongo/unittest/unittest.h"
+
+namespace {
+
+ using mongo::ShardType;
+ using mongo::BSONObj;
+
+ TEST(Validity, Empty) {
+ ShardType shard;
+ BSONObj emptyObj = BSONObj();
+ shard.parseBSON(emptyObj);
+ ASSERT_FALSE(shard.isValid(NULL));
+ }
+
+ TEST(Validity, OnlyMandatory) {
+ ShardType shard;
+ BSONObj obj = BSON(ShardType::name("shard0000") <<
+ ShardType::host("localhost:27017"));
+ shard.parseBSON(obj);
+ ASSERT_TRUE(shard.isValid(NULL));
+ }
+
+ TEST(Validity, AllOptionalsPresent) {
+ ShardType shard;
+ BSONObj obj = BSON(ShardType::name("shard0000") <<
+ ShardType::host("localhost:27017") <<
+ ShardType::draining(true) <<
+ ShardType::maxSize(100));
+ shard.parseBSON(obj);
+ ASSERT_TRUE(shard.isValid(NULL));
+ }
+
+} // unnamed namespace