summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/member_config.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/repl/member_config.cpp')
-rw-r--r--src/mongo/db/repl/member_config.cpp482
1 files changed, 235 insertions, 247 deletions
diff --git a/src/mongo/db/repl/member_config.cpp b/src/mongo/db/repl/member_config.cpp
index 02711adedd3..a6f8e311928 100644
--- a/src/mongo/db/repl/member_config.cpp
+++ b/src/mongo/db/repl/member_config.cpp
@@ -40,280 +40,268 @@
namespace mongo {
namespace repl {
- const std::string MemberConfig::kIdFieldName = "_id";
- const std::string MemberConfig::kVotesFieldName = "votes";
- const std::string MemberConfig::kPriorityFieldName = "priority";
- const std::string MemberConfig::kHostFieldName = "host";
- const std::string MemberConfig::kHiddenFieldName = "hidden";
- const std::string MemberConfig::kSlaveDelayFieldName = "slaveDelay";
- const std::string MemberConfig::kArbiterOnlyFieldName = "arbiterOnly";
- const std::string MemberConfig::kBuildIndexesFieldName = "buildIndexes";
- const std::string MemberConfig::kTagsFieldName = "tags";
- const std::string MemberConfig::kInternalVoterTagName = "$voter";
- const std::string MemberConfig::kInternalElectableTagName = "$electable";
- const std::string MemberConfig::kInternalAllTagName = "$all";
+const std::string MemberConfig::kIdFieldName = "_id";
+const std::string MemberConfig::kVotesFieldName = "votes";
+const std::string MemberConfig::kPriorityFieldName = "priority";
+const std::string MemberConfig::kHostFieldName = "host";
+const std::string MemberConfig::kHiddenFieldName = "hidden";
+const std::string MemberConfig::kSlaveDelayFieldName = "slaveDelay";
+const std::string MemberConfig::kArbiterOnlyFieldName = "arbiterOnly";
+const std::string MemberConfig::kBuildIndexesFieldName = "buildIndexes";
+const std::string MemberConfig::kTagsFieldName = "tags";
+const std::string MemberConfig::kInternalVoterTagName = "$voter";
+const std::string MemberConfig::kInternalElectableTagName = "$electable";
+const std::string MemberConfig::kInternalAllTagName = "$all";
namespace {
- const std::string kLegalMemberConfigFieldNames[] = {
- MemberConfig::kIdFieldName,
- MemberConfig::kVotesFieldName,
- MemberConfig::kPriorityFieldName,
- MemberConfig::kHostFieldName,
- MemberConfig::kHiddenFieldName,
- MemberConfig::kSlaveDelayFieldName,
- MemberConfig::kArbiterOnlyFieldName,
- MemberConfig::kBuildIndexesFieldName,
- MemberConfig::kTagsFieldName
- };
-
- const int kVotesFieldDefault = 1;
- const double kPriorityFieldDefault = 1.0;
- const Seconds kSlaveDelayFieldDefault(0);
- const bool kArbiterOnlyFieldDefault = false;
- const bool kHiddenFieldDefault = false;
- const bool kBuildIndexesFieldDefault = true;
-
- const Seconds kMaxSlaveDelay(3600 * 24 * 366);
+const std::string kLegalMemberConfigFieldNames[] = {MemberConfig::kIdFieldName,
+ MemberConfig::kVotesFieldName,
+ MemberConfig::kPriorityFieldName,
+ MemberConfig::kHostFieldName,
+ MemberConfig::kHiddenFieldName,
+ MemberConfig::kSlaveDelayFieldName,
+ MemberConfig::kArbiterOnlyFieldName,
+ MemberConfig::kBuildIndexesFieldName,
+ MemberConfig::kTagsFieldName};
+
+const int kVotesFieldDefault = 1;
+const double kPriorityFieldDefault = 1.0;
+const Seconds kSlaveDelayFieldDefault(0);
+const bool kArbiterOnlyFieldDefault = false;
+const bool kHiddenFieldDefault = false;
+const bool kBuildIndexesFieldDefault = true;
+
+const Seconds kMaxSlaveDelay(3600 * 24 * 366);
} // namespace
- Status MemberConfig::initialize(const BSONObj& mcfg, ReplicaSetTagConfig* tagConfig) {
- Status status = bsonCheckOnlyHasFields(
- "replica set member configuration", mcfg, kLegalMemberConfigFieldNames);
- if (!status.isOK())
- return status;
-
- //
- // Parse _id field.
- //
- BSONElement idElement = mcfg[kIdFieldName];
- if (idElement.eoo()) {
- return Status(ErrorCodes::NoSuchKey, str::stream() << kIdFieldName <<
- " field is missing");
- }
- if (!idElement.isNumber()) {
- return Status(ErrorCodes::TypeMismatch, str::stream() << kIdFieldName <<
- " field has non-numeric type " << typeName(idElement.type()));
- }
- _id = idElement.numberInt();
-
- //
- // Parse h field.
- //
- std::string hostAndPortString;
- status = bsonExtractStringField(mcfg, kHostFieldName, &hostAndPortString);
- if (!status.isOK())
- return status;
- boost::trim(hostAndPortString);
- status = _host.initialize(hostAndPortString);
- if (!status.isOK())
- return status;
- if (!_host.hasPort()) {
- // make port explicit even if default.
- _host = HostAndPort(_host.host(), _host.port());
- }
+Status MemberConfig::initialize(const BSONObj& mcfg, ReplicaSetTagConfig* tagConfig) {
+ Status status = bsonCheckOnlyHasFields(
+ "replica set member configuration", mcfg, kLegalMemberConfigFieldNames);
+ if (!status.isOK())
+ return status;
- //
- // Parse votes field.
- //
- BSONElement votesElement = mcfg[kVotesFieldName];
- if (votesElement.eoo()) {
- _votes = kVotesFieldDefault;
- }
- else if (votesElement.isNumber()) {
- _votes = votesElement.numberInt();
- }
- else {
- return Status(ErrorCodes::TypeMismatch, str::stream() << kVotesFieldName <<
- " field value has non-numeric type " <<
- typeName(votesElement.type()));
- }
+ //
+ // Parse _id field.
+ //
+ BSONElement idElement = mcfg[kIdFieldName];
+ if (idElement.eoo()) {
+ return Status(ErrorCodes::NoSuchKey, str::stream() << kIdFieldName << " field is missing");
+ }
+ if (!idElement.isNumber()) {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << kIdFieldName << " field has non-numeric type "
+ << typeName(idElement.type()));
+ }
+ _id = idElement.numberInt();
- //
- // Parse priority field.
- //
- BSONElement priorityElement = mcfg[kPriorityFieldName];
- if (priorityElement.eoo()) {
- _priority = kPriorityFieldDefault;
- }
- else if (priorityElement.isNumber()) {
- _priority = priorityElement.numberDouble();
- }
- else {
- return Status(ErrorCodes::TypeMismatch, str::stream() << kPriorityFieldName <<
- " field has non-numeric type " << typeName(priorityElement.type()));
- }
+ //
+ // Parse h field.
+ //
+ std::string hostAndPortString;
+ status = bsonExtractStringField(mcfg, kHostFieldName, &hostAndPortString);
+ if (!status.isOK())
+ return status;
+ boost::trim(hostAndPortString);
+ status = _host.initialize(hostAndPortString);
+ if (!status.isOK())
+ return status;
+ if (!_host.hasPort()) {
+ // make port explicit even if default.
+ _host = HostAndPort(_host.host(), _host.port());
+ }
- //
- // Parse arbiterOnly field.
- //
- status = bsonExtractBooleanFieldWithDefault(mcfg,
- kArbiterOnlyFieldName,
- kArbiterOnlyFieldDefault,
- &_arbiterOnly);
- if (!status.isOK())
- return status;
-
- //
- // Parse slaveDelay field.
- //
- BSONElement slaveDelayElement = mcfg[kSlaveDelayFieldName];
- if (slaveDelayElement.eoo()) {
- _slaveDelay = kSlaveDelayFieldDefault;
- }
- else if (slaveDelayElement.isNumber()) {
- _slaveDelay = Seconds(slaveDelayElement.numberInt());
- }
- else {
- return Status(ErrorCodes::TypeMismatch, str::stream() << kSlaveDelayFieldName <<
- " field value has non-numeric type " <<
- typeName(slaveDelayElement.type()));
- }
+ //
+ // Parse votes field.
+ //
+ BSONElement votesElement = mcfg[kVotesFieldName];
+ if (votesElement.eoo()) {
+ _votes = kVotesFieldDefault;
+ } else if (votesElement.isNumber()) {
+ _votes = votesElement.numberInt();
+ } else {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << kVotesFieldName << " field value has non-numeric type "
+ << typeName(votesElement.type()));
+ }
+
+ //
+ // Parse priority field.
+ //
+ BSONElement priorityElement = mcfg[kPriorityFieldName];
+ if (priorityElement.eoo()) {
+ _priority = kPriorityFieldDefault;
+ } else if (priorityElement.isNumber()) {
+ _priority = priorityElement.numberDouble();
+ } else {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << kPriorityFieldName << " field has non-numeric type "
+ << typeName(priorityElement.type()));
+ }
+
+ //
+ // Parse arbiterOnly field.
+ //
+ status = bsonExtractBooleanFieldWithDefault(
+ mcfg, kArbiterOnlyFieldName, kArbiterOnlyFieldDefault, &_arbiterOnly);
+ if (!status.isOK())
+ return status;
- //
- // Parse hidden field.
- //
- status = bsonExtractBooleanFieldWithDefault(mcfg,
- kHiddenFieldName,
- kHiddenFieldDefault,
- &_hidden);
- if (!status.isOK())
- return status;
-
- //
- // Parse buildIndexes field.
- //
- status = bsonExtractBooleanFieldWithDefault(mcfg,
- kBuildIndexesFieldName,
- kBuildIndexesFieldDefault,
- &_buildIndexes);
- if (!status.isOK())
- return status;
-
- //
- // Parse "tags" field.
- //
- _tags.clear();
- BSONElement tagsElement;
- status = bsonExtractTypedField(mcfg, kTagsFieldName, Object, &tagsElement);
- if (status.isOK()) {
- for (BSONObj::iterator tagIter(tagsElement.Obj()); tagIter.more();) {
- const BSONElement& tag = tagIter.next();
- if (tag.type() != String) {
- return Status(ErrorCodes::TypeMismatch, str::stream() << "tags." <<
- tag.fieldName() << " field has non-string value of type " <<
- typeName(tag.type()));
- }
- _tags.push_back(tagConfig->makeTag(tag.fieldNameStringData(),
- tag.valueStringData()));
+ //
+ // Parse slaveDelay field.
+ //
+ BSONElement slaveDelayElement = mcfg[kSlaveDelayFieldName];
+ if (slaveDelayElement.eoo()) {
+ _slaveDelay = kSlaveDelayFieldDefault;
+ } else if (slaveDelayElement.isNumber()) {
+ _slaveDelay = Seconds(slaveDelayElement.numberInt());
+ } else {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << kSlaveDelayFieldName << " field value has non-numeric type "
+ << typeName(slaveDelayElement.type()));
+ }
+
+ //
+ // Parse hidden field.
+ //
+ status =
+ bsonExtractBooleanFieldWithDefault(mcfg, kHiddenFieldName, kHiddenFieldDefault, &_hidden);
+ if (!status.isOK())
+ return status;
+
+ //
+ // Parse buildIndexes field.
+ //
+ status = bsonExtractBooleanFieldWithDefault(
+ mcfg, kBuildIndexesFieldName, kBuildIndexesFieldDefault, &_buildIndexes);
+ if (!status.isOK())
+ return status;
+
+ //
+ // Parse "tags" field.
+ //
+ _tags.clear();
+ BSONElement tagsElement;
+ status = bsonExtractTypedField(mcfg, kTagsFieldName, Object, &tagsElement);
+ if (status.isOK()) {
+ for (BSONObj::iterator tagIter(tagsElement.Obj()); tagIter.more();) {
+ const BSONElement& tag = tagIter.next();
+ if (tag.type() != String) {
+ return Status(ErrorCodes::TypeMismatch,
+ str::stream() << "tags." << tag.fieldName()
+ << " field has non-string value of type "
+ << typeName(tag.type()));
}
+ _tags.push_back(tagConfig->makeTag(tag.fieldNameStringData(), tag.valueStringData()));
}
- else if (ErrorCodes::NoSuchKey != status) {
- return status;
- }
+ } else if (ErrorCodes::NoSuchKey != status) {
+ return status;
+ }
- //
- // Add internal tags based on other member properties.
- //
-
- // Add a voter tag if this non-arbiter member votes; use _id for uniquity.
- const std::string id = str::stream() << _id;
- if (isVoter() && !_arbiterOnly) {
- _tags.push_back(tagConfig->makeTag(kInternalVoterTagName, id));
- }
+ //
+ // Add internal tags based on other member properties.
+ //
- // Add an electable tag if this member is electable.
- if (isElectable()) {
- _tags.push_back(tagConfig->makeTag(kInternalElectableTagName, id));
- }
+ // Add a voter tag if this non-arbiter member votes; use _id for uniquity.
+ const std::string id = str::stream() << _id;
+ if (isVoter() && !_arbiterOnly) {
+ _tags.push_back(tagConfig->makeTag(kInternalVoterTagName, id));
+ }
- // Add a tag for generic counting of this node.
- if (!_arbiterOnly) {
- _tags.push_back(tagConfig->makeTag(kInternalAllTagName, id));
- }
+ // Add an electable tag if this member is electable.
+ if (isElectable()) {
+ _tags.push_back(tagConfig->makeTag(kInternalElectableTagName, id));
+ }
- return Status::OK();
+ // Add a tag for generic counting of this node.
+ if (!_arbiterOnly) {
+ _tags.push_back(tagConfig->makeTag(kInternalAllTagName, id));
}
- Status MemberConfig::validate() const {
- if (_id < 0 || _id > 255) {
- return Status(ErrorCodes::BadValue, str::stream() << kIdFieldName <<
- " field value of " << _id << " is out of range.");
- }
+ return Status::OK();
+}
- if (_priority < 0 || _priority > 1000) {
- return Status(ErrorCodes::BadValue, str::stream() << kPriorityFieldName <<
- " field value of " << _priority << " is out of range");
- }
- if (_votes != 0 && _votes != 1) {
- return Status(ErrorCodes::BadValue, str::stream() << kVotesFieldName <<
- " field value is " << _votes << " but must be 0 or 1");
- }
- if (_arbiterOnly) {
- if (!_tags.empty()) {
- return Status(ErrorCodes::BadValue, "Cannot set tags on arbiters.");
- }
- if (!isVoter()) {
- return Status(ErrorCodes::BadValue, "Arbiter must vote (cannot have 0 votes)");
- }
- }
- if (_slaveDelay < Seconds(0) || _slaveDelay > kMaxSlaveDelay) {
- return Status(ErrorCodes::BadValue, str::stream() << kSlaveDelayFieldName <<
- " field value of " << durationCount<Seconds>(_slaveDelay) <<
- " seconds is out of range");
- }
- if (_slaveDelay > Seconds(0) && _priority != 0) {
- return Status(ErrorCodes::BadValue, "slaveDelay requires priority be zero");
- }
- if (_hidden && _priority != 0) {
- return Status(ErrorCodes::BadValue, "priority must be 0 when hidden=true");
+Status MemberConfig::validate() const {
+ if (_id < 0 || _id > 255) {
+ return Status(ErrorCodes::BadValue,
+ str::stream() << kIdFieldName << " field value of " << _id
+ << " is out of range.");
+ }
+
+ if (_priority < 0 || _priority > 1000) {
+ return Status(ErrorCodes::BadValue,
+ str::stream() << kPriorityFieldName << " field value of " << _priority
+ << " is out of range");
+ }
+ if (_votes != 0 && _votes != 1) {
+ return Status(ErrorCodes::BadValue,
+ str::stream() << kVotesFieldName << " field value is " << _votes
+ << " but must be 0 or 1");
+ }
+ if (_arbiterOnly) {
+ if (!_tags.empty()) {
+ return Status(ErrorCodes::BadValue, "Cannot set tags on arbiters.");
}
- if (!_buildIndexes && _priority != 0) {
- return Status(ErrorCodes::BadValue, "priority must be 0 when buildIndexes=false");
+ if (!isVoter()) {
+ return Status(ErrorCodes::BadValue, "Arbiter must vote (cannot have 0 votes)");
}
- return Status::OK();
}
+ if (_slaveDelay < Seconds(0) || _slaveDelay > kMaxSlaveDelay) {
+ return Status(ErrorCodes::BadValue,
+ str::stream() << kSlaveDelayFieldName << " field value of "
+ << durationCount<Seconds>(_slaveDelay)
+ << " seconds is out of range");
+ }
+ if (_slaveDelay > Seconds(0) && _priority != 0) {
+ return Status(ErrorCodes::BadValue, "slaveDelay requires priority be zero");
+ }
+ if (_hidden && _priority != 0) {
+ return Status(ErrorCodes::BadValue, "priority must be 0 when hidden=true");
+ }
+ if (!_buildIndexes && _priority != 0) {
+ return Status(ErrorCodes::BadValue, "priority must be 0 when buildIndexes=false");
+ }
+ return Status::OK();
+}
- bool MemberConfig::hasTags(const ReplicaSetTagConfig& tagConfig) const {
- for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin();
- tag != _tags.end();
- tag++) {
- std::string tagKey = tagConfig.getTagKey(*tag);
- if (tagKey[0] == '$') {
- // Filter out internal tags
- continue;
- }
- return true;
+bool MemberConfig::hasTags(const ReplicaSetTagConfig& tagConfig) const {
+ for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin(); tag != _tags.end();
+ tag++) {
+ std::string tagKey = tagConfig.getTagKey(*tag);
+ if (tagKey[0] == '$') {
+ // Filter out internal tags
+ continue;
}
- return false;
+ return true;
}
+ return false;
+}
- BSONObj MemberConfig::toBSON(const ReplicaSetTagConfig& tagConfig) const {
- BSONObjBuilder configBuilder;
- configBuilder.append("_id", _id);
- configBuilder.append("host", _host.toString());
- configBuilder.append("arbiterOnly", _arbiterOnly);
- configBuilder.append("buildIndexes", _buildIndexes);
- configBuilder.append("hidden", _hidden);
- configBuilder.append("priority", _priority);
-
- BSONObjBuilder tags(configBuilder.subobjStart("tags"));
- for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin();
- tag != _tags.end();
- tag++) {
- std::string tagKey = tagConfig.getTagKey(*tag);
- if (tagKey[0] == '$') {
- // Filter out internal tags
- continue;
- }
- tags.append(tagKey, tagConfig.getTagValue(*tag));
- }
- tags.done();
+BSONObj MemberConfig::toBSON(const ReplicaSetTagConfig& tagConfig) const {
+ BSONObjBuilder configBuilder;
+ configBuilder.append("_id", _id);
+ configBuilder.append("host", _host.toString());
+ configBuilder.append("arbiterOnly", _arbiterOnly);
+ configBuilder.append("buildIndexes", _buildIndexes);
+ configBuilder.append("hidden", _hidden);
+ configBuilder.append("priority", _priority);
- configBuilder.append("slaveDelay", durationCount<Seconds>(_slaveDelay));
- configBuilder.append("votes", getNumVotes());
- return configBuilder.obj();
+ BSONObjBuilder tags(configBuilder.subobjStart("tags"));
+ for (std::vector<ReplicaSetTag>::const_iterator tag = _tags.begin(); tag != _tags.end();
+ tag++) {
+ std::string tagKey = tagConfig.getTagKey(*tag);
+ if (tagKey[0] == '$') {
+ // Filter out internal tags
+ continue;
+ }
+ tags.append(tagKey, tagConfig.getTagValue(*tag));
}
+ tags.done();
+
+ configBuilder.append("slaveDelay", durationCount<Seconds>(_slaveDelay));
+ configBuilder.append("votes", getNumVotes());
+ return configBuilder.obj();
+}
} // namespace repl
} // namespace mongo