Наследование: CommandResult
        public void TestMaxWriteBatchSizeWhenNotServerSupplied()
        {
            var document = new BsonDocument
            {
                { "ok", 1 }
            };
            var result = new IsMasterResult(document);

            Assert.AreEqual(1000, result.MaxWriteBatchSize);
        }
        public void TestMaxMessageLengthWhenNotServerSuppliedUsesMaxBsonObjectSizeWhenLargerThanMongoDefaults()
        {
            var document = new BsonDocument
            {
                { "ok", 1 },
                { "maxBsonObjectSize", MongoDefaults.MaxMessageLength }
            };
            var result = new IsMasterResult(document);

            Assert.AreEqual(MongoDefaults.MaxMessageLength + 1024, result.MaxMessageLength);
        }
        public void TestMaxMessageLengthWhenServerSupplied()
        {
            var document = new BsonDocument
            {
                { "ok", 1 },
                { "maxMessageSizeBytes", 1000 },
                { "maxBsonObjectSize", 1000 }
            };
            var result = new IsMasterResult(document);

            Assert.AreEqual(1000, result.MaxMessageLength);
        }
        public void TestMaxMessageLengthWhenNotServerSuppliedUsesMongoDefaultsWhenLargerThanMaxBsonObjectSize()
        {
            var command = new CommandDocument("ismaster", 1);
            var document = new BsonDocument
            {
                { "ok", 1 },
                { "maxBsonObjectSize", MongoDefaults.MaxMessageLength - 2048 }
            };
            var result = new IsMasterResult();
            result.Initialize(command, document);

            Assert.AreEqual(MongoDefaults.MaxMessageLength, result.MaxMessageLength);
        }
        public void TestMaxMessageLengthWhenServerSupplied()
        {
            var command = new CommandDocument("ismaster", 1);
            var document = new BsonDocument
            {
                { "ok", 1 },
                { "maxMessageSizeBytes", 1000 },
                { "maxBsonObjectSize", 1000 }
            };
            var result = new IsMasterResult();
            result.Initialize(command, document);

            Assert.AreEqual(1000, result.MaxMessageLength);
        }
        // private methods
        private void LookupServerInformation(MongoConnection connection)
        {
            IsMasterResult isMasterResult = null;
            bool           ok             = false;

            try
            {
                var isMasterCommand = new CommandDocument("ismaster", 1);
                var tempResult      = connection.RunCommand("admin", QueryFlags.SlaveOk, isMasterCommand, false);
                isMasterResult = new IsMasterResult();
                isMasterResult.Initialize(isMasterCommand, tempResult.Response);
                if (!isMasterResult.Ok)
                {
                    throw new MongoCommandException(isMasterResult);
                }

                MongoServerBuildInfo buildInfo;
                var buildInfoCommand = new CommandDocument("buildinfo", 1);
                var buildInfoResult  = connection.RunCommand("admin", QueryFlags.SlaveOk, buildInfoCommand, false);
                if (buildInfoResult.Ok)
                {
                    buildInfo = MongoServerBuildInfo.FromCommandResult(buildInfoResult);
                }
                else
                {
                    // short term fix: if buildInfo fails due to auth we don't know the server version; see CSHARP-324
                    if (buildInfoResult.ErrorMessage != "need to login")
                    {
                        throw new MongoCommandException(buildInfoResult);
                    }
                    buildInfo = null;
                }

                ReplicaSetInformation   replicaSetInformation = null;
                MongoServerInstanceType instanceType          = MongoServerInstanceType.StandAlone;
                if (isMasterResult.ReplicaSetName != null)
                {
                    var peers = isMasterResult.Hosts.Concat(isMasterResult.Passives).Concat(isMasterResult.Arbiters).ToList();
                    replicaSetInformation = new ReplicaSetInformation(isMasterResult.ReplicaSetName, isMasterResult.Primary, peers, isMasterResult.Tags);
                    instanceType          = MongoServerInstanceType.ReplicaSetMember;
                }
                else if (isMasterResult.Message != null && isMasterResult.Message == "isdbgrid")
                {
                    instanceType = MongoServerInstanceType.ShardRouter;
                }

                var newServerInfo = new ServerInformation
                {
                    BuildInfo             = buildInfo,
                    InstanceType          = instanceType,
                    IsArbiter             = isMasterResult.IsArbiterOnly,
                    IsMasterResult        = isMasterResult,
                    IsPassive             = isMasterResult.IsPassive,
                    IsPrimary             = isMasterResult.IsPrimary,
                    IsSecondary           = isMasterResult.IsSecondary,
                    MaxDocumentSize       = isMasterResult.MaxBsonObjectSize,
                    MaxMessageLength      = isMasterResult.MaxMessageLength,
                    ReplicaSetInformation = replicaSetInformation
                };
                MongoServerState currentState;
                lock (_serverInstanceLock)
                {
                    currentState = _state;
                }
                SetState(currentState, newServerInfo);
                ok = true;
            }
            finally
            {
                if (!ok)
                {
                    ServerInformation currentServerInfo;
                    lock (_serverInstanceLock)
                    {
                        currentServerInfo = _serverInfo;
                    }

                    // keep the current instance type, build info, and replica set info
                    // as these aren't relevent to state and are likely still correct.
                    var newServerInfo = new ServerInformation
                    {
                        BuildInfo             = currentServerInfo.BuildInfo,
                        InstanceType          = currentServerInfo.InstanceType,
                        IsArbiter             = false,
                        IsMasterResult        = isMasterResult,
                        IsPassive             = false,
                        IsPrimary             = false,
                        IsSecondary           = false,
                        MaxDocumentSize       = currentServerInfo.MaxDocumentSize,
                        MaxMessageLength      = currentServerInfo.MaxMessageLength,
                        ReplicaSetInformation = currentServerInfo.ReplicaSetInformation
                    };

                    SetState(MongoServerState.Disconnected, newServerInfo);
                }
            }
        }
        // private methods
        private void LookupServerInformation(MongoConnection connection)
        {
            IsMasterResult isMasterResult = null;
            bool ok = false;
            try
            {
                var isMasterCommand = new CommandDocument("ismaster", 1);
                var tempResult = connection.RunCommand("admin", QueryFlags.SlaveOk, isMasterCommand, false);
                isMasterResult = new IsMasterResult();
                isMasterResult.Initialize(isMasterCommand, tempResult.Response);
                if (!isMasterResult.Ok)
                {
                    throw new MongoCommandException(isMasterResult);
                }

                MongoServerBuildInfo buildInfo;
                var buildInfoCommand = new CommandDocument("buildinfo", 1);
                var buildInfoResult = connection.RunCommand("admin", QueryFlags.SlaveOk, buildInfoCommand, false);
                if (buildInfoResult.Ok)
                {
                    buildInfo = MongoServerBuildInfo.FromCommandResult(buildInfoResult);
                }
                else
                {
                    // short term fix: if buildInfo fails due to auth we don't know the server version; see CSHARP-324
                    if (buildInfoResult.ErrorMessage != "need to login")
                    {
                        throw new MongoCommandException(buildInfoResult);
                    }
                    buildInfo = null;
                }

                ReplicaSetInformation replicaSetInformation = null;
                MongoServerInstanceType instanceType = MongoServerInstanceType.StandAlone;
                if (isMasterResult.ReplicaSetName != null)
                {
                    var tagSet = new ReplicaSetTagSet();
                    var peers = isMasterResult.Hosts.Concat(isMasterResult.Passives).Concat(isMasterResult.Arbiters).ToList();
                    replicaSetInformation = new ReplicaSetInformation(isMasterResult.ReplicaSetName, isMasterResult.Primary, peers, tagSet);
                    instanceType = MongoServerInstanceType.ReplicaSetMember;
                }
                else if (isMasterResult.Message != null && isMasterResult.Message == "isdbgrid")
                {
                    instanceType = MongoServerInstanceType.ShardRouter;
                }

                lock (_serverInstanceLock)
                {
                    _isMasterResult = isMasterResult;
                    _maxDocumentSize = isMasterResult.MaxBsonObjectSize;
                    _maxMessageLength = isMasterResult.MaxMessageLength;
                    _buildInfo = buildInfo;
                    this.SetState(MongoServerState.Connected,
                        instanceType,
                        isMasterResult.IsPrimary,
                        isMasterResult.IsSecondary,
                        isMasterResult.IsPassive,
                        isMasterResult.IsArbiterOnly,
                        replicaSetInformation);
                }
                ok = true;
            }
            finally
            {
                if (!ok)
                {
                    lock (_serverInstanceLock)
                    {
                        _isMasterResult = isMasterResult;
                        _maxDocumentSize = MongoDefaults.MaxDocumentSize;
                        _maxMessageLength = MongoDefaults.MaxMessageLength;
                        _buildInfo = null;
                        this.SetState(MongoServerState.Disconnected, _instanceType, false, false, false, false, null);
                    }
                }
            }
        }
        // private methods
        private void LookupServerInformation(MongoConnection connection)
        {
            IsMasterResult isMasterResult = null;
            bool ok = false;
            try
            {
                var isMasterCommand = new CommandDocument("ismaster", 1);
                var tempResult = connection.RunCommand("admin", QueryFlags.SlaveOk, isMasterCommand, false);
                isMasterResult = new IsMasterResult();
                isMasterResult.Initialize(isMasterCommand, tempResult.Response);
                if (!isMasterResult.Ok)
                {
                    throw new MongoCommandException(isMasterResult);
                }

                MongoServerBuildInfo buildInfo;
                var buildInfoCommand = new CommandDocument("buildinfo", 1);
                var buildInfoResult = connection.RunCommand("admin", QueryFlags.SlaveOk, buildInfoCommand, false);
                if (buildInfoResult.Ok)
                {
                    buildInfo = MongoServerBuildInfo.FromCommandResult(buildInfoResult);
                }
                else
                {
                    // short term fix: if buildInfo fails due to auth we don't know the server version; see CSHARP-324
                    if (buildInfoResult.ErrorMessage != "need to login")
                    {
                        throw new MongoCommandException(buildInfoResult);
                    }
                    buildInfo = null;
                }

                ReplicaSetInformation replicaSetInformation = null;
                MongoServerInstanceType instanceType = MongoServerInstanceType.StandAlone;
                if (isMasterResult.ReplicaSetName != null)
                {
                    var peers = isMasterResult.Hosts.Concat(isMasterResult.Passives).Concat(isMasterResult.Arbiters).ToList();
                    replicaSetInformation = new ReplicaSetInformation(isMasterResult.ReplicaSetName, isMasterResult.Primary, peers, isMasterResult.Tags);
                    instanceType = MongoServerInstanceType.ReplicaSetMember;
                }
                else if (isMasterResult.Message != null && isMasterResult.Message == "isdbgrid")
                {
                    instanceType = MongoServerInstanceType.ShardRouter;
                }

                var newServerInfo = new ServerInformation
                {
                    BuildInfo = buildInfo,
                    InstanceType = instanceType,
                    IsArbiter = isMasterResult.IsArbiterOnly,
                    IsMasterResult = isMasterResult,
                    IsPassive = isMasterResult.IsPassive,
                    IsPrimary = isMasterResult.IsPrimary,
                    IsSecondary = isMasterResult.IsSecondary,
                    MaxDocumentSize = isMasterResult.MaxBsonObjectSize,
                    MaxMessageLength = isMasterResult.MaxMessageLength,
                    ReplicaSetInformation = replicaSetInformation
                };
                MongoServerState currentState;
                lock (_serverInstanceLock)
                {
                    currentState = _state;
                }
                SetState(currentState, newServerInfo);
                ok = true;
            }
            finally
            {
                if (!ok)
                {
                    ServerInformation currentServerInfo;
                    lock (_serverInstanceLock)
                    {
                        currentServerInfo = _serverInfo;
                    }

                    // keep the current instance type, build info, and replica set info
                    // as these aren't relevent to state and are likely still correct.
                    var newServerInfo = new ServerInformation
                    {
                        BuildInfo = currentServerInfo.BuildInfo,
                        InstanceType = currentServerInfo.InstanceType,
                        IsArbiter = false,
                        IsMasterResult = isMasterResult,
                        IsPassive = false,
                        IsPrimary = false,
                        IsSecondary = false,
                        MaxDocumentSize = currentServerInfo.MaxDocumentSize,
                        MaxMessageLength = currentServerInfo.MaxMessageLength,
                        ReplicaSetInformation = currentServerInfo.ReplicaSetInformation
                    };

                    SetState(MongoServerState.Disconnected, newServerInfo);
                }
            }
        }
        // private methods
        private void LookupServerInformation(MongoConnection connection)
        {
            IsMasterResult isMasterResult = null;
            bool           ok             = false;

            try
            {
                var isMasterCommand = new CommandDocument("ismaster", 1);
                isMasterResult = RunCommandAs <IsMasterResult>(connection, "admin", isMasterCommand);

                MongoServerBuildInfo buildInfo;
                try
                {
                    var buildInfoCommand = new CommandDocument("buildinfo", 1);
                    var buildInfoResult  = RunCommandAs <CommandResult>(connection, "admin", buildInfoCommand);
                    buildInfo = MongoServerBuildInfo.FromCommandResult(buildInfoResult);
                }
                catch (MongoCommandException ex)
                {
                    // short term fix: if buildInfo fails due to auth we don't know the server version; see CSHARP-324
                    if (ex.CommandResult.ErrorMessage != "need to login")
                    {
                        throw;
                    }
                    buildInfo = null;
                }

                ReplicaSetInformation   replicaSetInformation = null;
                MongoServerInstanceType instanceType          = MongoServerInstanceType.StandAlone;
                if (isMasterResult.IsReplicaSet)
                {
                    var peers = isMasterResult.Hosts.Concat(isMasterResult.Passives).Concat(isMasterResult.Arbiters).ToList();
                    replicaSetInformation = new ReplicaSetInformation(isMasterResult.ReplicaSetName, isMasterResult.Primary, peers, isMasterResult.Tags, isMasterResult.ReplicaSetConfigVersion);
                    instanceType          = MongoServerInstanceType.ReplicaSetMember;
                }
                else if (isMasterResult.Message != null && isMasterResult.Message == "isdbgrid")
                {
                    instanceType = MongoServerInstanceType.ShardRouter;
                }

                var featureContext = new FeatureContext
                {
                    BuildInfo          = buildInfo,
                    Connection         = connection,
                    IsMasterResult     = isMasterResult,
                    ServerInstanceType = instanceType
                };
                var featureSet = new FeatureSetDetector().DetectFeatureSet(featureContext);

                var newServerInfo = new ServerInformation
                {
                    BuildInfo             = buildInfo,
                    FeatureSet            = featureSet,
                    InstanceType          = instanceType,
                    IsArbiter             = isMasterResult.IsArbiterOnly,
                    IsMasterResult        = isMasterResult,
                    IsPassive             = isMasterResult.IsPassive,
                    IsPrimary             = isMasterResult.IsPrimary,
                    IsSecondary           = isMasterResult.IsSecondary,
                    MaxBatchCount         = isMasterResult.MaxWriteBatchSize,
                    MaxDocumentSize       = isMasterResult.MaxBsonObjectSize,
                    MaxMessageLength      = isMasterResult.MaxMessageLength,
                    ReplicaSetInformation = replicaSetInformation
                };
                MongoServerState currentState;
                lock (_serverInstanceLock)
                {
                    currentState = _state;
                }
                SetState(currentState, newServerInfo);
                ok = true;
            }
            finally
            {
                if (!ok)
                {
                    ServerInformation currentServerInfo;
                    lock (_serverInstanceLock)
                    {
                        currentServerInfo = _serverInfo;
                    }

                    // keep the current instance type, build info, and replica set info
                    // as these aren't relevent to state and are likely still correct.
                    var newServerInfo = new ServerInformation
                    {
                        BuildInfo             = currentServerInfo.BuildInfo,
                        FeatureSet            = currentServerInfo.FeatureSet,
                        InstanceType          = currentServerInfo.InstanceType,
                        IsArbiter             = false,
                        IsMasterResult        = isMasterResult,
                        IsPassive             = false,
                        IsPrimary             = false,
                        IsSecondary           = false,
                        MaxDocumentSize       = currentServerInfo.MaxDocumentSize,
                        MaxMessageLength      = currentServerInfo.MaxMessageLength,
                        MaxBatchCount         = currentServerInfo.MaxBatchCount,
                        ReplicaSetInformation = currentServerInfo.ReplicaSetInformation
                    };

                    SetState(MongoServerState.Disconnected, newServerInfo);
                }
            }
        }