summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Pulo <kevin.pulo@mongodb.com>2018-02-07 05:26:36 +0000
committerKevin Pulo <kevin.pulo@mongodb.com>2018-07-02 04:44:42 +0000
commit0d6a9242c11b99ddadcfb6e86a850b6ba487530a (patch)
tree0fcf6d731e02d8422eaf736b6a2fe2432669d353
parent6838f0b80639cb3647364570107ffcabe8e95d02 (diff)
downloadmongo-r3.4.16.tar.gz
SERVER-25746 store advisoryHostFQDNs in config.mongosr3.4.16-rc0r3.4.16
(cherry picked from commit 75c8414afea212e79b27dae42cfd2930bdfd6eea)
-rw-r--r--src/mongo/s/catalog/type_mongos.cpp27
-rw-r--r--src/mongo/s/catalog/type_mongos.h9
-rw-r--r--src/mongo/s/catalog/type_mongos_test.cpp90
-rw-r--r--src/mongo/s/sharding_uptime_reporter.cpp17
4 files changed, 124 insertions, 19 deletions
diff --git a/src/mongo/s/catalog/type_mongos.cpp b/src/mongo/s/catalog/type_mongos.cpp
index c656f59b4ee..c5e02a69f15 100644
--- a/src/mongo/s/catalog/type_mongos.cpp
+++ b/src/mongo/s/catalog/type_mongos.cpp
@@ -43,6 +43,7 @@ const BSONField<long long> MongosType::uptime("up");
const BSONField<bool> MongosType::waiting("waiting");
const BSONField<std::string> MongosType::mongoVersion("mongoVersion");
const BSONField<long long> MongosType::configVersion("configVersion");
+const BSONField<BSONArray> MongosType::advisoryHostFQDNs("advisoryHostFQDNs");
StatusWith<MongosType> MongosType::fromBSON(const BSONObj& source) {
MongosType mt;
@@ -95,6 +96,26 @@ StatusWith<MongosType> MongosType::fromBSON(const BSONObj& source) {
mt._configVersion = mtConfigVersion;
}
+ if (source.hasField(advisoryHostFQDNs.name())) {
+ mt._advisoryHostFQDNs = std::vector<std::string>();
+ BSONElement array;
+ Status status = bsonExtractTypedField(source, advisoryHostFQDNs.name(), Array, &array);
+ if (!status.isOK())
+ return status;
+
+ BSONObjIterator it(array.Obj());
+ while (it.more()) {
+ BSONElement arrayElement = it.next();
+ if (arrayElement.type() != String) {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << "Elements in \"" << advisoryHostFQDNs.name()
+ << "\" array must be strings but found "
+ << typeName(arrayElement.type()));
+ }
+ mt._advisoryHostFQDNs->push_back(arrayElement.String());
+ }
+ }
+
return mt;
}
@@ -133,6 +154,8 @@ BSONObj MongosType::toBSON() const {
builder.append(mongoVersion.name(), getMongoVersion());
if (_configVersion)
builder.append(configVersion.name(), getConfigVersion());
+ if (_advisoryHostFQDNs)
+ builder.append(advisoryHostFQDNs.name(), getAdvisoryHostFQDNs());
return builder.obj();
}
@@ -163,6 +186,10 @@ void MongosType::setConfigVersion(const long long configVersion) {
_configVersion = configVersion;
}
+void MongosType::setAdvisoryHostFQDNs(const std::vector<std::string>& advisoryHostFQDNs) {
+ _advisoryHostFQDNs = advisoryHostFQDNs;
+}
+
std::string MongosType::toString() const {
return toBSON().toString();
}
diff --git a/src/mongo/s/catalog/type_mongos.h b/src/mongo/s/catalog/type_mongos.h
index 02e7fea601b..e0fb0ea84b1 100644
--- a/src/mongo/s/catalog/type_mongos.h
+++ b/src/mongo/s/catalog/type_mongos.h
@@ -30,6 +30,7 @@
#include <boost/optional.hpp>
#include <string>
+#include <vector>
#include "mongo/db/jsobj.h"
#include "mongo/util/time_support.h"
@@ -53,6 +54,7 @@ public:
static const BSONField<bool> waiting;
static const BSONField<std::string> mongoVersion;
static const BSONField<long long> configVersion;
+ static const BSONField<BSONArray> advisoryHostFQDNs;
/**
* Returns the BSON representation of the entry.
@@ -112,6 +114,11 @@ public:
}
void setConfigVersion(const long long configVersion);
+ std::vector<std::string> getAdvisoryHostFQDNs() const {
+ return _advisoryHostFQDNs.value_or(std::vector<std::string>());
+ }
+ void setAdvisoryHostFQDNs(const std::vector<std::string>& advisoryHostFQDNs);
+
private:
// Convention: (M)andatory, (O)ptional, (S)pecial rule.
@@ -127,6 +134,8 @@ private:
boost::optional<std::string> _mongoVersion;
// (O) the config version of the pinging mongos
boost::optional<long long> _configVersion;
+ // (O) the results of hostname canonicalization on the pinging mongos
+ boost::optional<std::vector<std::string>> _advisoryHostFQDNs;
};
} // namespace mongo
diff --git a/src/mongo/s/catalog/type_mongos_test.cpp b/src/mongo/s/catalog/type_mongos_test.cpp
index 8fc449ab6f7..dad38d140cf 100644
--- a/src/mongo/s/catalog/type_mongos_test.cpp
+++ b/src/mongo/s/catalog/type_mongos_test.cpp
@@ -39,21 +39,24 @@ namespace {
using namespace mongo;
TEST(Validity, MissingName) {
- BSONObj obj =
- BSON(MongosType::ping(Date_t::fromMillisSinceEpoch(1)) << MongosType::uptime(100)
- << MongosType::waiting(false)
- << MongosType::mongoVersion("x.x.x")
- << MongosType::configVersion(0));
+ BSONObj obj = BSON(MongosType::ping(Date_t::fromMillisSinceEpoch(1))
+ << MongosType::uptime(100)
+ << MongosType::waiting(false)
+ << MongosType::mongoVersion("x.x.x")
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSONArrayBuilder().arr()));
auto mongosTypeResult = MongosType::fromBSON(obj);
ASSERT_EQ(ErrorCodes::NoSuchKey, mongosTypeResult.getStatus());
}
TEST(Validity, MissingPing) {
- BSONObj obj = BSON(MongosType::name("localhost:27017") << MongosType::uptime(100)
- << MongosType::waiting(false)
- << MongosType::mongoVersion("x.x.x")
- << MongosType::configVersion(0));
+ BSONObj obj = BSON(MongosType::name("localhost:27017")
+ << MongosType::uptime(100)
+ << MongosType::waiting(false)
+ << MongosType::mongoVersion("x.x.x")
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSONArrayBuilder().arr()));
auto mongosTypeResult = MongosType::fromBSON(obj);
ASSERT_EQ(ErrorCodes::NoSuchKey, mongosTypeResult.getStatus());
@@ -64,7 +67,8 @@ TEST(Validity, MissingUp) {
<< MongosType::ping(Date_t::fromMillisSinceEpoch(1))
<< MongosType::waiting(false)
<< MongosType::mongoVersion("x.x.x")
- << MongosType::configVersion(0));
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSONArrayBuilder().arr()));
auto mongosTypeResult = MongosType::fromBSON(obj);
ASSERT_EQ(ErrorCodes::NoSuchKey, mongosTypeResult.getStatus());
@@ -75,7 +79,8 @@ TEST(Validity, MissingWaiting) {
<< MongosType::ping(Date_t::fromMillisSinceEpoch(1))
<< MongosType::uptime(100)
<< MongosType::mongoVersion("x.x.x")
- << MongosType::configVersion(0));
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSONArrayBuilder().arr()));
auto mongosTypeResult = MongosType::fromBSON(obj);
ASSERT_EQ(ErrorCodes::NoSuchKey, mongosTypeResult.getStatus());
@@ -86,7 +91,8 @@ TEST(Validity, MissingMongoVersion) {
<< MongosType::ping(Date_t::fromMillisSinceEpoch(1))
<< MongosType::uptime(100)
<< MongosType::waiting(false)
- << MongosType::configVersion(0));
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSONArrayBuilder().arr()));
auto mongosTypeResult = MongosType::fromBSON(obj);
ASSERT_OK(mongosTypeResult.getStatus());
@@ -104,7 +110,8 @@ TEST(Validity, MissingConfigVersion) {
<< MongosType::ping(Date_t::fromMillisSinceEpoch(1))
<< MongosType::uptime(100)
<< MongosType::waiting(false)
- << MongosType::mongoVersion("x.x.x"));
+ << MongosType::mongoVersion("x.x.x")
+ << MongosType::advisoryHostFQDNs(BSONArrayBuilder().arr()));
auto mongosTypeResult = MongosType::fromBSON(obj);
ASSERT_OK(mongosTypeResult.getStatus());
@@ -117,7 +124,7 @@ TEST(Validity, MissingConfigVersion) {
ASSERT_OK(mtype.validate());
}
-TEST(Validity, Valid) {
+TEST(Validity, MissingAdvisoryHostFQDNs) {
BSONObj obj = BSON(MongosType::name("localhost:27017")
<< MongosType::ping(Date_t::fromMillisSinceEpoch(1))
<< MongosType::uptime(100)
@@ -126,8 +133,59 @@ TEST(Validity, Valid) {
<< MongosType::configVersion(0));
auto mongosTypeResult = MongosType::fromBSON(obj);
+ ASSERT_OK(mongosTypeResult.getStatus());
+
MongosType& mType = mongosTypeResult.getValue();
+ // advisoryHostFQDNs is optional
+ ASSERT_OK(mType.validate());
+}
+TEST(Validity, EmptyAdvisoryHostFQDNs) {
+ BSONObj obj = BSON(MongosType::name("localhost:27017")
+ << MongosType::ping(Date_t::fromMillisSinceEpoch(1))
+ << MongosType::uptime(100)
+ << MongosType::waiting(false)
+ << MongosType::mongoVersion("x.x.x")
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSONArrayBuilder().arr()));
+
+ auto mongosTypeResult = MongosType::fromBSON(obj);
+ ASSERT_OK(mongosTypeResult.getStatus());
+
+ MongosType& mType = mongosTypeResult.getValue();
+ ASSERT_OK(mType.validate());
+
+ ASSERT_EQUALS(mType.getAdvisoryHostFQDNs().size(), 0UL);
+}
+
+TEST(Validity, BadTypeAdvisoryHostFQDNs) {
+ BSONObj obj = BSON(MongosType::name("localhost:27017")
+ << MongosType::ping(Date_t::fromMillisSinceEpoch(1))
+ << MongosType::uptime(100)
+ << MongosType::waiting(false)
+ << MongosType::mongoVersion("x.x.x")
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSON_ARRAY("foo" << 0 << "baz")));
+
+ auto mongosTypeResult = MongosType::fromBSON(obj);
+ ASSERT_EQ(ErrorCodes::TypeMismatch, mongosTypeResult.getStatus());
+}
+
+TEST(Validity, Valid) {
+ BSONObj obj = BSON(MongosType::name("localhost:27017")
+ << MongosType::ping(Date_t::fromMillisSinceEpoch(1))
+ << MongosType::uptime(100)
+ << MongosType::waiting(false)
+ << MongosType::mongoVersion("x.x.x")
+ << MongosType::configVersion(0)
+ << MongosType::advisoryHostFQDNs(BSON_ARRAY("foo"
+ << "bar"
+ << "baz")));
+
+ auto mongosTypeResult = MongosType::fromBSON(obj);
+ ASSERT_OK(mongosTypeResult.getStatus());
+
+ MongosType& mType = mongosTypeResult.getValue();
ASSERT_OK(mType.validate());
ASSERT_EQUALS(mType.getName(), "localhost:27017");
@@ -136,6 +194,10 @@ TEST(Validity, Valid) {
ASSERT_EQUALS(mType.getWaiting(), false);
ASSERT_EQUALS(mType.getMongoVersion(), "x.x.x");
ASSERT_EQUALS(mType.getConfigVersion(), 0);
+ ASSERT_EQUALS(mType.getAdvisoryHostFQDNs().size(), 3UL);
+ ASSERT_EQUALS(mType.getAdvisoryHostFQDNs()[0], "foo");
+ ASSERT_EQUALS(mType.getAdvisoryHostFQDNs()[1], "bar");
+ ASSERT_EQUALS(mType.getAdvisoryHostFQDNs()[2], "baz");
}
TEST(Validity, BadType) {
diff --git a/src/mongo/s/sharding_uptime_reporter.cpp b/src/mongo/s/sharding_uptime_reporter.cpp
index 61a438dd93e..a7eefc14e03 100644
--- a/src/mongo/s/sharding_uptime_reporter.cpp
+++ b/src/mongo/s/sharding_uptime_reporter.cpp
@@ -42,6 +42,7 @@
#include "mongo/util/exit.h"
#include "mongo/util/log.h"
#include "mongo/util/mongoutils/str.h"
+#include "mongo/util/net/hostname_canonicalization.h"
#include "mongo/util/net/sock.h"
#include "mongo/util/version.h"
@@ -50,15 +51,18 @@ namespace {
const Seconds kUptimeReportInterval(10);
-std::string constructInstanceIdString() {
- return str::stream() << getHostNameCached() << ":" << serverGlobalParams.port;
+std::string constructInstanceIdString(const std::string& hostName) {
+ return str::stream() << hostName << ":" << serverGlobalParams.port;
}
/**
* Reports the uptime status of the current instance to the config.pings collection. This method
* is best-effort and never throws.
*/
-void reportStatus(OperationContext* txn, const std::string& instanceId, const Timer& upTimeTimer) {
+void reportStatus(OperationContext* txn,
+ const std::string& instanceId,
+ const std::string& hostName,
+ const Timer& upTimeTimer) {
MongosType mType;
mType.setName(instanceId);
mType.setPing(jsTime());
@@ -66,6 +70,8 @@ void reportStatus(OperationContext* txn, const std::string& instanceId, const Ti
// balancer is never active in mongos. Here for backwards compatibility only.
mType.setWaiting(true);
mType.setMongoVersion(VersionInfoInterface::instance().version().toString());
+ mType.setAdvisoryHostFQDNs(
+ getHostFQDNs(hostName, HostnameCanonicalizationMode::kForwardAndReverse));
try {
Grid::get(txn)->catalogClient(txn)->updateConfigDocument(
@@ -95,13 +101,14 @@ void ShardingUptimeReporter::startPeriodicThread() {
_thread = stdx::thread([this] {
Client::initThread("Uptime reporter");
- const std::string instanceId(constructInstanceIdString());
+ const std::string hostName(getHostNameCached());
+ const std::string instanceId(constructInstanceIdString(hostName));
const Timer upTimeTimer;
while (!inShutdown()) {
{
auto txn = cc().makeOperationContext();
- reportStatus(txn.get(), instanceId, upTimeTimer);
+ reportStatus(txn.get(), instanceId, hostName, upTimeTimer);
auto status =
Grid::get(txn.get())->getBalancerConfiguration()->refreshAndCheck(txn.get());