Ejemplo n.º 1
0
    Status UpdatePositionArgs::initialize(const BSONObj& argsObj) {
        Status status = bsonCheckOnlyHasFields("UpdatePositionArgs",
                                               argsObj,
                                               kLegalUpdatePositionFieldNames);

        if (!status.isOK())
            return status;

        // grab the array of changes
        BSONElement updateArray;
        status = bsonExtractTypedField(argsObj, kUpdateArrayFieldName, Array, &updateArray);
        if (!status.isOK())
            return status;

        // now parse each array entry into an update
        BSONObjIterator i(updateArray.Obj());
        while(i.more()) {
            BSONObj entry = i.next().Obj();
            status = bsonCheckOnlyHasFields("UpdateInfoArgs",
                                            entry,
                                            kLegalUpdateInfoFieldNames);
            if (!status.isOK())
                return status;

            OpTime ts;
            status = bsonExtractOpTimeField(entry, kOpTimeFieldName, &ts);
            if (!status.isOK())
                return status;

            // TODO(spencer): The following three fields are optional in 2.8, but should be made
            // required or ignored in 3.0
            long long cfgver;
            status = bsonExtractIntegerFieldWithDefault(entry, kConfigVersionFieldName, -1, &cfgver);
            if (!status.isOK())
                return status;

            OID rid;
            status = bsonExtractOIDFieldWithDefault(entry, kMemberRIDFieldName, OID(), &rid);
            if (!status.isOK())
                return status;

            long long memberID;
            status = bsonExtractIntegerFieldWithDefault(entry, kMemberIdFieldName, -1, &memberID);
            if (!status.isOK())
                return status;

            _updates.push_back(UpdateInfo(rid, ts, cfgver, memberID));
        }

        return Status::OK();
    }
Ejemplo n.º 2
0
Status HandshakeArgs::initialize(const BSONObj& argsObj) {
    Status status = bsonCheckOnlyHasFields("HandshakeArgs", argsObj, kLegalHandshakeFieldNames);
    if (!status.isOK())
        return status;

    BSONElement oid;
    status = bsonExtractTypedField(argsObj, kRIDFieldName, jstOID, &oid);
    if (!status.isOK())
        return status;
    _rid = oid.OID();
    _hasRid = true;

    status = bsonExtractIntegerField(argsObj, kMemberIdFieldName, &_memberId);
    if (!status.isOK()) {
        // field not necessary for master slave, do not return NoSuchKey Error
        if (status != ErrorCodes::NoSuchKey) {
            return status;
        }
        _memberId = -1;
    } else {
        _hasMemberId = true;
    }

    return Status::OK();
}
Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) {
    Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes", argsObj, kLegalArgsFieldNames);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_cfgver);
    if (!status.isOK())
        return status;

    status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName);
    if (!status.isOK())
        return status;

    status = bsonExtractBooleanField(argsObj, kDryRunFieldName, &_dryRun);
    if (!status.isOK())
        return status;

    status = bsonExtractOpTimeField(argsObj, kLastCommittedOpFieldName, &_lastCommittedOp);
    if (!status.isOK())
        return status;

    return Status::OK();
}
Ejemplo n.º 4
0
    Status ReplSetRequestVotesResponse::initialize(const BSONObj& argsObj) {
        Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes",
                                               argsObj,
                                               kLegalResponseFieldNames);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
        if (!status.isOK())
            return status;

        status = bsonExtractBooleanField(argsObj, kVoteGrantedFieldName, &_voteGranted);
        if (!status.isOK())
            return status;

        status = bsonExtractStringField(argsObj, kReasonFieldName, &_reason);
        if (!status.isOK())
            return status;

        status = bsonExtractBooleanField(argsObj, kOkFieldName, &_ok);
        if (!status.isOK())
            return status;

        return Status::OK();
    }
Ejemplo n.º 5
0
    Status LastVote::initialize(const BSONObj& argsObj) {
        Status status = bsonCheckOnlyHasFields("VotedFar",
                                               argsObj,
                                               kLegalFieldNames);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId);
        if (!status.isOK())
            return status;

        return Status::OK();
    }
Status ReplSetHeartbeatArgs::initialize(const BSONObj& argsObj) {
    Status status =
        bsonCheckOnlyHasFields("ReplSetHeartbeatArgs", argsObj, kLegalHeartbeatFieldNames);
    if (!status.isOK())
        return status;

    status = bsonExtractBooleanFieldWithDefault(argsObj, kCheckEmptyFieldName, false, &_checkEmpty);
    if (!status.isOK())
        return status;
    _hasCheckEmpty = true;

    status = bsonExtractIntegerField(argsObj, kProtocolVersionFieldName, &_protocolVersion);
    if (!status.isOK())
        return status;
    _hasProtocolVersion = true;

    status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_configVersion);
    if (!status.isOK())
        return status;
    _hasConfigVersion = true;

    status = bsonExtractIntegerFieldWithDefault(argsObj, kSenderIdFieldName, -1, &_senderId);
    if (!status.isOK())
        return status;
    _hasSenderId = true;

    status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName);
    if (!status.isOK())
        return status;
    _hasSetName = true;

    std::string hostAndPortString;
    status =
        bsonExtractStringFieldWithDefault(argsObj, kSenderHostFieldName, "", &hostAndPortString);
    if (!status.isOK())
        return status;

    if (!hostAndPortString.empty()) {
        status = _senderHost.initialize(hostAndPortString);
        if (!status.isOK())
            return status;
        _hasSenderHost = true;
    }

    return Status::OK();
}
Ejemplo n.º 7
0
    Status ReplSetRequestVotesArgs::initialize(const BSONObj& argsObj) {
        Status status = bsonCheckOnlyHasFields("ReplSetRequestVotes",
                                               argsObj,
                                               kLegalArgsFieldNames);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kTermFieldName, &_term);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kCandidateIdFieldName, &_candidateId);
        if (!status.isOK())
            return status;

        status = bsonExtractIntegerField(argsObj, kConfigVersionFieldName, &_cfgver);
        if (!status.isOK())
            return status;

        status = bsonExtractStringField(argsObj, kSetNameFieldName, &_setName);
        if (!status.isOK())
            return status;

        // extracting the lastCommittedOp is a bit of a process
        BSONObj lastCommittedOp = argsObj[kLastCommittedOpFieldName].Obj();
        Timestamp ts;
        status = bsonExtractTimestampField(lastCommittedOp, kOpTimeFieldName, &ts);
        if (!status.isOK())
            return status;
        long long term;
        status = bsonExtractIntegerField(lastCommittedOp, kTermFieldName, &term);
        if (!status.isOK())
            return status;
        _lastCommittedOp = OpTime(lastCommittedOp[kOpTimeFieldName].timestamp(),
                                  lastCommittedOp[kTermFieldName].Long());

        return Status::OK();
    }
Ejemplo n.º 8
0
    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());
        }

        //
        // Parse votes field.
        //
        BSONElement votesElement = mcfg[kVotesFieldName];
        int votes;
        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()));
        }
        if (votes != 0 && votes != 1) {
            return Status(ErrorCodes::BadValue, str::stream() << kVotesFieldName <<
                          " field value is " << votesElement.numberInt() << " but must be 0 or 1");
        }
        _isVoter = bool(votes);

        //
        // 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 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;
        }

        return Status::OK();
    }
Status ReplSetHeartbeatResponseV1::initialize(const BSONObj& doc) {
    Status status = bsonCheckOnlyHasFields("ReplSetHeartbeatResponse",
                                           doc,
                                           kLegalHeartbeatFieldNames);
    if (!status.isOK())
        return status;

    status = bsonExtractBooleanField(doc, kIsReplSetFieldName, &_isReplSet);
    if (!status.isOK())
        return status;

    status = bsonExtractStringField(doc, kReplSetFieldName, &_setName);
    if (!status.isOK())
        return status;

    long long stateInt;
    status = bsonExtractIntegerField(doc, kMemberStateFieldName, &stateInt);
    if (!status.isOK())
        return status;
    if (stateInt < 0 || stateInt > MemberState::RS_MAX) {
        return Status(ErrorCodes::BadValue, str::stream() << "Value for \"" <<
                      kMemberStateFieldName << "\" in response to replSetHeartbeat is "
                      "out of range; legal values are non-negative and no more than " <<
                      MemberState::RS_MAX);
    }
    _state = MemberState(static_cast<int>(stateInt));

    // extracting the lastCommittedOp is a bit of a process
    BSONObj lastOpTime = doc[kLastOpTimeFieldName].Obj();
    Timestamp ts;
    status = bsonExtractTimestampField(lastOpTime, kOpTimeFieldName, &ts);
    if (!status.isOK())
        return status;
    long long term;
    status = bsonExtractIntegerField(lastOpTime, kTermFieldName, &term);
    if (!status.isOK())
        return status;
    _lastOpTime = OpTime(lastOpTime[kOpTimeFieldName].timestamp(),
                         lastOpTime[kTermFieldName].Long());


    status = bsonExtractStringField(doc, kSyncSourceFieldName, &_syncingTo);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(doc, kConfigVersionFieldName, &_configVersion);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(doc, kPrimaryIdFieldName, &_primaryId);
    if (!status.isOK())
        return status;

    status = bsonExtractIntegerField(doc, kTermFieldName, &_term);
    if (!status.isOK())
        return status;

    const BSONElement hasDataElement = doc[kHasDataFieldName];
    _hasDataSet = !hasDataElement.eoo();
    _hasData = hasDataElement.trueValue();

    const BSONElement rsConfigElement = doc[kConfigFieldName];
    if (rsConfigElement.eoo()) {
        _configSet = false;
        _config = ReplicaSetConfig();
        return Status::OK();
    }
    else if (rsConfigElement.type() != Object) {
        return Status(ErrorCodes::TypeMismatch, str::stream() << "Expected \"" <<
                      kConfigFieldName << "\" in response to replSetHeartbeat to have type "
                      "Object, but found " << typeName(rsConfigElement.type()));
    }
    _configSet = true;
    return _config.initialize(rsConfigElement.Obj());
}
Ejemplo n.º 10
0
Status ReplicaSetConfig::initialize(const BSONObj& cfg) {
    _isInitialized = false;
    _members.clear();
    Status status =
        bsonCheckOnlyHasFields("replica set configuration", cfg, kLegalConfigTopFieldNames);
    if (!status.isOK())
        return status;

    //
    // Parse replSetName
    //
    status = bsonExtractStringField(cfg, kIdFieldName, &_replSetName);
    if (!status.isOK())
        return status;

    //
    // Parse version
    //
    status = bsonExtractIntegerField(cfg, kVersionFieldName, &_version);
    if (!status.isOK())
        return status;

    //
    // Parse members
    //
    BSONElement membersElement;
    status = bsonExtractTypedField(cfg, kMembersFieldName, Array, &membersElement);
    if (!status.isOK())
        return status;

    for (BSONObj::iterator membersIterator(membersElement.Obj()); membersIterator.more();) {
        BSONElement memberElement = membersIterator.next();
        if (memberElement.type() != Object) {
            return Status(ErrorCodes::TypeMismatch,
                          str::stream() << "Expected type of " << kMembersFieldName << "."
                                        << memberElement.fieldName() << " to be Object, but found "
                                        << typeName(memberElement.type()));
        }
        _members.resize(_members.size() + 1);
        const auto& memberBSON = memberElement.Obj();
        status = _members.back().initialize(memberBSON, &_tagConfig);
        if (!status.isOK())
            return Status(ErrorCodes::InvalidReplicaSetConfig,
                          str::stream() << status.toString() << " for member:" << memberBSON);
    }

    //
    // Parse configServer
    //
    status = bsonExtractBooleanFieldWithDefault(cfg, kConfigServerFieldName, false, &_configServer);
    if (!status.isOK()) {
        return status;
    }

    //
    // Parse protocol version
    //
    status = bsonExtractIntegerField(cfg, kProtocolVersionFieldName, &_protocolVersion);
    if (!status.isOK() && status != ErrorCodes::NoSuchKey) {
        return status;
    }

    //
    // Parse settings
    //
    BSONElement settingsElement;
    status = bsonExtractTypedField(cfg, kSettingsFieldName, Object, &settingsElement);
    BSONObj settings;
    if (status.isOK()) {
        settings = settingsElement.Obj();
    } else if (status != ErrorCodes::NoSuchKey) {
        return status;
    }
    status = _parseSettingsSubdocument(settings);
    if (!status.isOK())
        return status;

    _calculateMajorities();
    _addInternalWriteConcernModes();
    _isInitialized = true;
    return Status::OK();
}